Comment: | Merge trunk into branch "wii-u" |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | wii-u |
Files: | files | file ages | folders |
SHA3-256: |
a2973418de4df1231674470bb4307036 |
User & Date: | js on 2022-07-15 18:09:53 |
Other Links: | branch diff | manifest | tags |
2022-07-15
| ||
18:14 | tests: Add target to generate tests.rpx check-in: 834ddf94fd user: js tags: wii-u | |
18:09 | Merge trunk into branch "wii-u" check-in: a2973418de user: js tags: wii-u | |
2022-07-14
| ||
15:15 | utils/ofhttp: Improve Unicode detection on Windows check-in: 0c7c78f397 user: js tags: trunk | |
2020-11-03
| ||
01:07 | configure: Add flags for Wii U check-in: 5b8a7e4d0d user: js tags: wii-u | |
Modified .fossil-settings/clean-glob from [8cc139c114] to [0c0ff942fb].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | *.a *.bundle *.dep *.dll *.dylib *.exe *.framework *.library *.map *.o *.so *.so.* */.deps .deps aclocal.m4 autom4te.cache boot.dol buildsys.mk config.h config.h.in config.log config.status configure docs extra.mk | > > | > < | > < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | *.a *.bundle *.dep *.dll *.dylib *.exe *.framework *.library *.map *.o *.sl *.so *.so.* */.deps .deps aclocal.m4 autom4te.cache boot.dol buildsys.mk config.h config.h.in config.log config.status configure docs extra.mk generators/library/gen_libraries generators/unicode/gen_tables src/Info.plist 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/terminal/terminal_tests tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp |
Modified .fossil-settings/ignore-glob from [9af6ddf1c8] to [13af81fd69].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | *.a *.bundle *.dep *.dll *.dylib *.exe *.framework *.library *.map *.o *.orig *.so *.so.* */.deps .deps .git aclocal.m4 autom4te.cache boot.dol buildsys.mk config.h config.h.in config.log config.status configure docs extra.mk | > > | > < | > < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | *.a *.bundle *.dep *.dll *.dylib *.exe *.framework *.library *.map *.o *.orig *.sl *.so *.so.* */.deps .deps .git aclocal.m4 autom4te.cache boot.dol buildsys.mk config.h config.h.in config.log config.status configure docs extra.mk generators/library/gen_libraries generators/unicode/gen_tables src/Info.plist 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/terminal/terminal_tests tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp |
Modified .github/ISSUE_TEMPLATE/config.yml from [c578ed1d2f] to [ee9213e864].
︙ | ︙ | |||
11 12 13 14 15 16 17 | - name: ObjFW Forum url: https://objfw.nil.im/forum about: Please use this if you have questions or want support. - name: ObjFW Matrix Room url: https://matrix.to/#/%23objfw:nil.im about: Please use this for interactive questions and support. - name: ObjFW IRC Channel | > > > > > > > > > > > > > > > | > > > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | - name: ObjFW Forum url: https://objfw.nil.im/forum about: Please use this if you have questions or want support. - name: ObjFW Matrix Room url: https://matrix.to/#/%23objfw:nil.im about: Please use this for interactive questions and support. - name: ObjFW IRC Channel url: https://webchat.oftc.net/?channels=%23objfw about: Please use this for interactive questions and support - it is bridged to the Matrix room above. - name: ObjFW Slack Channel url: https://objfw.nil.im/slack about: Please use this for interactive questions and support - it is bridged to the Matrix room above. - name: ObjFW Discord Channel url: https://objfw.nil.im/discord about: Please use this for interactive questions and support - it is bridged to the Matrix room above. - name: ObjFW Telegram Room url: https://t.me/objfw about: Please use this for interactive questions and support - it is bridged to the Matrix room above. - name: ObjFW Gitter Room url: https://gitter.im/ObjFW/ObjFW about: Please use this for interactive questions and support - it is bridged to the Matrix room above. |
Added .github/workflows/amiga-gcc.yml version [16471286d2].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | name: amiga-gcc 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:m68k-amigaos - uses: actions/checkout@v2 - name: autogen.sh run: ./autogen.sh - name: configure run: | docker run \ -e PATH="/opt/m68k-amigaos/bin:$PATH" \ -v "$PWD:/objfw" \ amigadev/crosstools:m68k-amigaos \ sh -c 'cd /objfw && ./configure --host=m68k-amigaos ${{ matrix.configure_flags }}' - name: make run: | docker run \ -e PATH="/opt/m68k-amigaos/bin:$PATH" \ -v "$PWD:/objfw" \ amigadev/crosstools:m68k-amigaos \ sh -c "cd /objfw && make -j$(nproc)" - name: make install run: | docker run \ -e PATH="/opt/m68k-amigaos/bin:$PATH" \ -v "$PWD:/objfw" \ amigadev/crosstools:m68k-amigaos \ sh -c "cd /objfw && make -j$(nproc)" |
Added .github/workflows/ios.yml version [dd34f22809].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | name: ios on: [push, pull_request] jobs: build: runs-on: macos-latest strategy: matrix: arch: - arm64 - x86_64 configure_flags: - - --disable-shared steps: - name: Install dependencies run: brew install autoconf automake - uses: actions/checkout@v2 - name: autogen.sh run: ./autogen.sh - name: configure run: | export IPHONEOS_DEPLOYMENT_TARGET="9.0" if [ "${{ matrix.arch}}" = "x86_64" ]; then sdk="iphonesimulator" else sdk="iphoneos" fi export OBJC="clang -isysroot $(xcrun --sdk $sdk --show-sdk-path)" export OBJC="$OBJC -arch ${{ matrix.arch }}" ./configure --host=${{ matrix.arch }}-apple-darwin \ ${{ matrix.configure_flags }} - name: make run: make -j$(sysctl -n hw.logicalcpu) - name: make install run: sudo make install |
Added .github/workflows/macos-10.15.yml version [0b4e6d02a3].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | name: macos-10.15 on: [push, pull_request] jobs: tests: runs-on: macos-10.15 strategy: matrix: configure_flags: - - --disable-threads - --disable-threads --disable-sockets - --disable-threads --disable-files - --disable-threads --disable-sockets --disable-files - --disable-sockets - --disable-sockets --disable-files - --disable-files - --disable-shared steps: - name: Install dependencies run: brew install autoconf automake - uses: actions/checkout@v2 - name: autogen.sh run: ./autogen.sh - name: configure run: ./configure ${{ matrix.configure_flags }} - name: make run: make -j$(sysctl -n hw.logicalcpu) - name: make check run: make check - name: make install run: sudo make install |
Added .github/workflows/macos-11.yml version [d79ffc1fb9].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | name: macos-11 on: [push, pull_request] jobs: tests: runs-on: macos-11 strategy: matrix: configure_flags: - - --disable-threads - --disable-threads --disable-sockets - --disable-threads --disable-files - --disable-threads --disable-sockets --disable-files - --disable-sockets - --disable-sockets --disable-files - --disable-files - --disable-shared steps: - name: Install dependencies run: brew install autoconf automake - uses: actions/checkout@v2 - name: autogen.sh run: ./autogen.sh - name: configure run: ./configure ${{ matrix.configure_flags }} - name: make run: make -j$(sysctl -n hw.logicalcpu) - name: make check run: make check - name: make install run: sudo make install |
Added .github/workflows/morphos.yml version [0f27c2ab37].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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)" |
Added .github/workflows/nintendo-3ds.yml version [67061ee611].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | name: nintendo-3ds on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - name: Install dependencies run: docker pull devkitpro/devkitarm - uses: actions/checkout@v2 - name: autogen.sh run: ./autogen.sh - name: configure run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitarm \ sh -c 'cd /objfw && ./configure --host=arm-none-eabi --with-3ds' - name: make run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitarm \ sh -c "cd /objfw && make -j$(nproc)" - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitarm \ sh -c "cd /objfw && make -j$(nproc)" |
Added .github/workflows/nintendo-ds.yml version [3d41e0f5f7].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | name: nintendo-ds on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - name: Install dependencies run: docker pull devkitpro/devkitarm - uses: actions/checkout@v2 - name: autogen.sh run: ./autogen.sh - name: configure run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitarm \ sh -c 'cd /objfw && ./configure --host=arm-none-eabi --with-nds' - name: make run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitarm \ sh -c "cd /objfw && make -j$(nproc)" - name: make install run: | docker run \ -e DEVKITPRO=/opt/devkitpro \ -e PATH="/opt/devkitpro/devkitARM/bin:$PATH" \ -v "$PWD:/objfw" \ devkitpro/devkitarm \ sh -c "cd /objfw && make -j$(nproc)" |
Added .github/workflows/ubuntu-18.04-32bit.yml version [96c9a8ae41].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | name: ubuntu-18.04, 32 bit on: [push, pull_request] jobs: tests: runs-on: ubuntu-18.04 strategy: matrix: configure_flags: - --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-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 }} - name: make run: make -j$(nproc) - name: make check run: make check - name: make install run: sudo make install |
Added .github/workflows/ubuntu-18.04-gcc-32bit.yml version [0e720701c6].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | name: ubuntu-18.04, GCC, 32 bit on: [push, pull_request] jobs: tests: runs-on: ubuntu-18.04 strategy: matrix: configure_flags: - --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-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 }} - name: make run: make -j$(nproc) - name: make check run: make check - name: make install run: sudo make install |
Added .github/workflows/ubuntu-18.04-gcc.yml version [9e75cc2f04].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | name: ubuntu-18.04, GCC on: [push, pull_request] jobs: 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 - --with-tls=gnutls - --with-tls=gnutls --disable-shared steps: - name: Install dependencies 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 }} - name: make run: make -j$(nproc) - name: make check run: make check - name: make install run: sudo make install |
Added .github/workflows/ubuntu-18.04.yml version [d0186b3566].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | name: ubuntu-18.04 on: [push, pull_request] jobs: 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 - --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 }} - name: make run: make -j$(nproc) - name: make check run: make check - name: make install run: sudo make install |
Added .github/workflows/ubuntu-20.04-32bit.yml version [6af581a780].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | name: ubuntu-20.04, 32 bit on: [push, pull_request] jobs: tests: runs-on: ubuntu-20.04 strategy: matrix: configure_flags: - --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-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 }} - name: make run: make -j$(nproc) - name: make check run: make check - name: make install run: sudo make install |
Added .github/workflows/ubuntu-20.04-gcc-32bit.yml version [16adbb51e7].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | name: ubuntu-20.04, GCC, 32 bit on: [push, pull_request] jobs: tests: runs-on: ubuntu-20.04 strategy: matrix: configure_flags: - --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-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 }} - name: make run: make -j$(nproc) - name: make check run: make check - name: make install run: sudo make install |
Added .github/workflows/ubuntu-20.04-gcc.yml version [dd262654f6].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | name: ubuntu-20.04, GCC on: [push, pull_request] jobs: 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 - --with-tls=gnutls - --with-tls=gnutls --disable-shared steps: - name: Install dependencies 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 }} - name: make run: make -j$(nproc) - name: make check run: make check - name: make install run: sudo make install |
Added .github/workflows/ubuntu-20.04.yml version [051ed40d72].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | name: ubuntu-20.04 on: [push, pull_request] jobs: 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 - --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 }} - name: make run: make -j$(nproc) - name: make check run: make check - name: make install run: sudo make install |
Added .github/workflows/wii.yml version [39c842705b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | name: wii 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' - 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)" |
Modified .gitignore from [1a9a1a32ef] to [fdb1296647].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | *.a *.bundle *.dep *.dll *.dylib *.exe *.framework *.library *.map *.o *.orig *.so *.so.* .deps .fslckout _FOSSIL_ aclocal.m4 autom4te.cache boot.dol buildsys.mk config.h config.h.in config.log config.status configure docs extra.mk | > > | > < | > < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | *.a *.bundle *.dep *.dll *.dylib *.exe *.framework *.library *.map *.o *.orig *.sl *.so *.so.* .deps .fslckout _FOSSIL_ aclocal.m4 autom4te.cache boot.dol buildsys.mk config.h config.h.in config.log config.status configure docs extra.mk generators/library/gen_libraries generators/unicode/gen_tables src/Info.plist 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/terminal/terminal_tests tests/tests tests/tests.3dsx tests/tests.arm9 tests/tests.nds utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp |
Deleted .travis.yml version [0619e15749].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted .travis/before_install.sh version [479fa2374a].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted .travis/build.sh version [02fcddbdad].
|
| < < < < < < < < < < < < < < < < < < < < |
Deleted .travis/script.sh version [6432052d0a].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified Doxyfile from [51b1f8245c] to [f4ff92fbc3].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | PROJECT_NAME = "ObjFW" OUTPUT_DIRECTORY = docs/ INPUT = src src/exceptions src/runtime FILE_PATTERNS = *.h *.m HTML_OUTPUT = . GENERATE_LATEX = NO HIDE_UNDOC_CLASSES = YES HIDE_UNDOC_MEMBERS = YES PREDEFINED = __OBJC__ \ DOXYGEN \ OF_BOXABLE \ OF_CONSUMED \ OF_DESIGNATED_INITIALIZER \ OF_GENERIC(...)= \ OF_HAVE_BLOCKS \ OF_HAVE_FILES \ | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | PROJECT_NAME = "ObjFW" OUTPUT_DIRECTORY = docs/ INPUT = src src/exceptions src/runtime FILE_PATTERNS = *.h *.m HTML_OUTPUT = . HAVE_DOT = NO GENERATE_LATEX = NO HIDE_UNDOC_CLASSES = YES HIDE_UNDOC_MEMBERS = YES TYPEDEF_HIDES_STRUCT = YES PREDEFINED = __OBJC__ \ _Nonnull \ _Nullable \ DOXYGEN \ OF_BOXABLE \ OF_CONSUMED \ OF_DESIGNATED_INITIALIZER \ OF_GENERIC(...)= \ OF_HAVE_BLOCKS \ OF_HAVE_FILES \ |
︙ | ︙ |
Modified Makefile from [d58557a5a6] to [63e28abf9d].
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | include buildsys.mk .PHONY: docs release utils tests: src docs: rm -fr docs doxygen >/dev/null release: docs echo "Generating tarball for version ${PACKAGE_VERSION}..." rm -fr objfw-${PACKAGE_VERSION} objfw-${PACKAGE_VERSION}.tar \ objfw-${PACKAGE_VERSION}.tar.gz fossil tarball --name objfw-${PACKAGE_VERSION} current - \ | > > > | < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | include buildsys.mk .PHONY: docs release utils tests: src check: tests cd tests && ${MAKE} -s run docs: rm -fr docs doxygen >/dev/null release: docs echo "Generating tarball for version ${PACKAGE_VERSION}..." rm -fr objfw-${PACKAGE_VERSION} objfw-${PACKAGE_VERSION}.tar \ objfw-${PACKAGE_VERSION}.tar.gz fossil tarball --name objfw-${PACKAGE_VERSION} current - \ --exclude '.cirrus*,.fossil*,.git*' | ofarc -ttgz -xq - cp configure config.h.in objfw-${PACKAGE_VERSION}/ ofarc -cq objfw-${PACKAGE_VERSION}.tar \ $$(find objfw-${PACKAGE_VERSION} | sort) rm -fr objfw-${PACKAGE_VERSION} gzip -9 objfw-${PACKAGE_VERSION}.tar rm -f objfw-${PACKAGE_VERSION}.tar gpg -b objfw-${PACKAGE_VERSION}.tar.gz || true |
︙ | ︙ |
Modified PLATFORMS.md from [d1e497fd99] to [aaef200c73].
︙ | ︙ | |||
63 64 65 66 67 68 69 70 71 72 73 74 75 76 | ----- * OS version: r1-alpha4 * Architectures: x86 * Compilers: Clang 3.2, GCC 4.6.3 * Runtimes: ObjFW iOS --- * Architectures: ARMv7, ARM64 * Compilers: Clang * Runtimes: Apple | > > > > > > > > > > > | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | ----- * OS version: r1-alpha4 * Architectures: x86 * Compilers: Clang 3.2, GCC 4.6.3 * Runtimes: ObjFW HP-UX ----- * OS versions: 11i v1 (PA-RISC 2.0), 11i v3 (Itanium) * Architectures: Itanium, PA-RISC 2.0 * Compilers: GCC 4.7.2, GCC 7.5.0 * Runtimes: ObjFW * Notes: Exception handling on Itanium in 32 bit mode is broken, you need to use 64 bit mode by passing `OBJC="gcc -mlp64"` to `configure`. iOS --- * Architectures: ARMv7, ARM64 * Compilers: Clang * Runtimes: Apple |
︙ | ︙ | |||
90 91 92 93 94 95 96 97 98 99 100 | ----- * 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 MorphOS ------- | > > > > > > > > > > | | < | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | ----- * 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 * Architectures: PowerPC * Compilers: GCC 9.3.0 * Runtimes: ObjFW NetBSD ------ * OS Versions: 5.1-9.0 * Architectures: ARM, ARM (big endian, BE8 mode), MIPS (O32), PowerPC, SPARC, |
︙ | ︙ | |||
181 182 183 184 185 186 187 | * Runtimes: ObjFW * Limitations: No threads Windows ------- | | | | > | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | * Runtimes: ObjFW * Limitations: No threads Windows ------- * 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, 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 14.0.4 from msys2 (AArch64) * Runtimes: ObjFW Others ------ Basically, it should run on any POSIX system to which GCC >= 4.6 or a recent |
︙ | ︙ |
Modified README.md from [f866fd61d7] to [939967b8be].
1 2 | There are three ways you are probably reading this right now: | | | | < > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | There are three ways you are probably reading this right now: * On [ObjFW](https://objfw.nil.im/)'s homepage, via Fossil's web interface * On [GitHub](https://github.com/ObjFW/ObjFW) * Via an editor or pager, by opening `README.md` from a clone or tarball ObjFW is developed using Fossil, so if you are reading this on GitHub or any other place, you are most likely using a mirror. <h1 id="table-of-contents">Table of Contents</h1> * [What is ObjFW?](#what) * [License](#license) * [Releases](#releases) * [Cloning the repository](#cloning) * [Installation](#installation) * [macOS and iOS](#macos-and-ios) * [Building as a framework](#building-framework) * [Using the macOS or iOS framework in Xcode](#framework-in-xcode) * [Broken Xcode versions](#broken-xcode-versions) * [Windows](#windows) * [Getting MSYS2](#getting-msys2) * [Setting up MSYS2](#setting-up-msys2) * [Getting, building and installing ObjFW](#steps-windows) * [Nintendo DS, Nintendo 3DS and Wii](#nintendo) * [Nintendo DS](#nintendo-ds) * [Nintendo 3DS](#nintendo-3ds) * [Wii](#wii) * [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) <h1 id="what">What is ObjFW?</h1> ObjFW is a portable, lightweight framework for the Objective-C language. It enables you to write an application in Objective-C that will run on any |
︙ | ︙ | |||
104 105 106 107 108 109 110 | The main advantage of cloning the Fossil repository over cloning the Git repository is that you also get all the tickets, wiki pages, etc. <h2 id="cloning-fossil">Fossil</h2> Clone the Fossil repository like this: | | < < > > > > > > > | > | > > > > > | | | > | | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | The main advantage of cloning the Fossil repository over cloning the Git repository is that you also get all the tickets, wiki pages, etc. <h2 id="cloning-fossil">Fossil</h2> Clone the Fossil repository like this: $ fossil clone https://objfw.nil.im You can then use Fossil's web interface to browse the timeline, tickets, wiki pages, etc.: $ cd objfw $ fossil ui It's also possible to open the same local repository multiple times, so that you have multiple working directories all backed by the same local repository. In order to verify the signature of the currently checked out checkin, you can use: $ fossil artifact current | gpg --verify 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. <h2 id="cloning-git">Git</h2> To clone the Git repository, use the following: $ git clone https://github.com/ObjFW/ObjFW Git commits are not signed, so if you want to check the signature of an individual commit, branch head or tag, please use Fossil. <h1 id="installation">Installation</h1> To install ObjFW, just run the following commands: $ ./configure $ make $ 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 <h2 id="macos-and-ios">macOS and iOS</h2> <h3 id="building-framework">Building as a framework</h3> When building for macOS or iOS, everything is built as a `.framework` by default if `--disable-shared` has not been specified to `./configure`. The frameworks will end up in `$PREFIX/Library/Frameworks`. To build for macOS, just follow the <a href="#installation">regular instructions</a> 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, 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 arm64 -arch x86_64" $ export OBJCPP="$clang -arch arm64 -E" $ export IPHONEOS_DEPLOYMENT_TARGET="9.0" $ ./configure --prefix=/usr/local/iossim --host=arm64-apple-darwin <h3 id="framework-in-xcode">Using the macOS or iOS framework in Xcode</h3> To use the macOS framework in Xcode, you need to add the `.framework`s to your project and add the following flags to `Other C Flags`: -fconstant-string-class=OFConstantString -fno-constant-cfstrings |
︙ | ︙ | |||
207 208 209 210 211 212 213 | there are many MinGW versions that behave slightly differently and often cause problems. <h3 id="getting-msys2">Getting MSYS2</h3> The first thing to install is [MSYS2](https://www.msys2.org) to provide a basic UNIX-like environment for Windows. Unfortunately, the binaries are not | | < | | < | < < | < | < > < > | < < > | | < < | < > | < | > | | | < | | | | < | | < < | | | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | there are many MinGW versions that behave slightly differently and often cause problems. <h3 id="getting-msys2">Getting MSYS2</h3> The first thing to install is [MSYS2](https://www.msys2.org) to provide a basic UNIX-like environment for Windows. Unfortunately, the binaries are not signed, so make sure you download it via HTTPS. However, packages you download and install via MSYS2 are cryptographically signed. <h3 id="setting-up-msys2">Setting up MSYS2</h3> MSYS2 currently supports 5 different [environments](https://www.msys2.org/docs/environments/). All of them except for the one called just "MSYS" are supported, but which packages you need to install depends on the environment(s) you want to use. For MINGW64, use: $ pacman -Syu mingw-w64-x86_64-clang mingw-w64-x86_64-fossil For UCRT64, use: $ pacman -Syu mingw-w64-ucrt-x86_64-clang mingw-w64-ucrt-x86_64-fossil For CLANG64, use: $ pacman -Syu mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-fossil For MINGW32, use: $ pacman -Syu mingw-w64-i686-clang mingw-w64-i686-fossil When using `pacman` to install the packages, `pacman` might tell you to close the window. If it does so, close the window, restart MSYS2 and execute the `pacman` command again. There is nothing wrong with installing multiple environments, as MSYS2 has created shortcuts for each of them in your start menu. Just make sure to use the correct shortcut for the environment you want to use. Finally, install a few more things that are common between all environments: $ pacman -S autoconf automake make <h3 id="steps-windows">Getting, building and installing ObjFW</h3> Start the MSYS2 using the shortcut for the environment you want to use and check out ObjFW: $ fossil clone https://objfw.nil.im You can also download a release tarball if you want. Now `cd` to the newly checked out repository and build and install it: $ ./autogen.sh && ./configure && make -j16 install If everything was successful, you can now build projects using ObjFW for Windows using the normal `objfw-compile` and friends. <h2 id="nintendo">Nintendo DS, Nintendo 3DS and Wii</h2> Download and install [devkitPro](https://devkitpro.org/wiki/Getting_Started). <h3 id="nintendo-ds">Nintendo DS</h3> |
︙ | ︙ | |||
313 314 315 316 317 318 319 | $ objfw-new app MyFirstApp This creates a file `MyFirstApp.m`. The `-[applicationDidFinishLaunching]` method is called as soon as ObjFW finished all initialization. Use this as the entry point to your own code. For example, you could add the following line there to create a "Hello World": | | | | | | > > > > > > > > > > > > > > > > > > > > > > | 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | $ objfw-new app MyFirstApp This creates a file `MyFirstApp.m`. The `-[applicationDidFinishLaunching]` method is called as soon as ObjFW finished all initialization. Use this as the entry point to your own code. For example, you could add the following line there to create a "Hello World": [OFStdOut writeLine: @"Hello World!"]; You can compile your new app using `objfw-compile`: $ objfw-compile -o MyFirstApp MyFirstApp.m `objfw-compile` is a tool that allows building applications and libraries using ObjFW without needing a full-blown build system. If you want to use your own build system, you can get the necessary flags from `objfw-config`. <h1 id="documentation">Documentation</h1> You can find the documentation for released versions of ObjFW [here](https://objfw.nil.im/docs/). In order to build the documentation yourself (necessary to have documentation for trunk / master), you need to have [Doxygen](https://www.doxygen.nl) installed. Once installed, you can build the documentation from the root directory of the repository: $ make docs <h1 id="bugs">Bugs and feature requests</h1> If you find any bugs or have feature requests, please [file a new bug](https://objfw.nil.im/tktnew) in the [bug tracker](https://objfw.nil.im/reportlist). Alternatively, feel free to send a mail to js@nil.im! <h1 id="support">Support and community</h1> If you have any questions about ObjFW or would like to talk to other ObjFW users, the following venues are available: * The [forum](https://objfw.nil.im/forum) * A [Matrix room](https://matrix.to/#/%23objfw:nil.im) * An IRC channel named `#objfw` on `irc.oftc.net` ([Web chat](https://webchat.oftc.net/?channels=%23objfw)), bridged to the Matrix room above * A [Slack channel](https://objfw.nil.im/slack), bridged to the Matrix room above * A [Discord channel](https://objfw.nil.im/discord), bridged to the Matrix room above * A [Telegram room](https://t.me/objfw), bridged to the Matrix room above * 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! <h1 id="donating">Donating</h1> If you want to donate to ObjFW, you can read about possible ways to do so [here](https://objfw.nil.im/wiki?name=Donating). <h1 id="thanks">Thanks</h1> * 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! <h1 id="commercial-use">Commercial use</h1> 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. |
Modified build-aux/config.guess from [3b75d9d5f8] to [a7bb5831a2].
1 2 | #! /bin/sh # Attempt to guess a canonical system name. | | | | 1 2 3 4 5 6 7 8 9 10 11 12 | #! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2019 Free Software Foundation, Inc. timestamp='2019-01-03' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but |
︙ | ︙ | |||
46 47 48 49 50 51 52 | Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." |
︙ | ︙ | |||
80 81 82 83 84 85 86 | done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi | < < > > > > | < < | > | | | | | < | | | | | > | | | | | | | | | | > | | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { : "${TMPDIR=/tmp}" # shellcheck disable=SC2039 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$driver" break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu set_cc_for_build cat <<-EOF > "$dummy.c" #include <features.h> #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else |
︙ | ︙ | |||
176 177 178 179 180 181 182 183 184 185 186 187 | # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ "/sbin/$sysctl" 2>/dev/null || \ "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; | > | | > > | | | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ "/sbin/$sysctl" 2>/dev/null || \ "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` case "$UNAME_MACHINE_ARCH" in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earm*) arch="${UNAME_MACHINE_ARCH#e}" arch="${arch%eb}" arch="${arch%hf}" endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine="${arch}${endian}"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "$UNAME_MACHINE_ARCH" in earm*) expr='s/v[0-9]//;s/earm/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "$machine-${os}${release}${abi-}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` |
︙ | ︙ | |||
379 380 381 382 383 384 385 | s390x:SunOS:*:*) echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) | > > > > > > > > > > > > > | | | 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | s390x:SunOS:*:*) echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) set_cc_for_build SUN_ARCH=sparc # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __sparcv9'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=sparcv9 fi fi echo "$SUN_ARCH"-sun-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ |
︙ | ︙ | |||
478 479 480 481 482 483 484 | VAX*:ULTRIX*:*:*) echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) | | | 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 | VAX*:ULTRIX*:*:*) echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include <stdio.h> /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif |
︙ | ︙ | |||
575 576 577 578 579 580 581 | else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then | | | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 | else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include <sys/systemcfg.h> main() { if (!__power_pc()) exit(1); |
︙ | ︙ | |||
656 657 658 659 660 661 662 | 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "$HP_ARCH" = "" ]; then | | | 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 | 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "$HP_ARCH" = "" ]; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include <stdlib.h> #include <unistd.h> int main () |
︙ | ︙ | |||
696 697 698 699 700 701 702 | EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ "$HP_ARCH" = hppa2.0w ] then | | | 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 | EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ "$HP_ARCH" = hppa2.0w ] then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 |
︙ | ︙ | |||
722 723 724 725 726 727 728 | echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) | | | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 | echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include <unistd.h> int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns |
︙ | ︙ | |||
835 836 837 838 839 840 841 842 843 844 845 846 847 848 | echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) | > > > > > > > > > > > | 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi else echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf fi exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) |
︙ | ︙ | |||
877 878 879 880 881 882 883 | echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; i*:UWIN*:*) echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) | | | | | 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 | echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; i*:UWIN*:*) echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; *:Minix:*:*) echo "$UNAME_MACHINE"-unknown-minix exit ;; aarch64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" |
︙ | ︙ | |||
918 919 920 921 922 923 924 | if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) | | | 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 | if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP |
︙ | ︙ | |||
967 968 969 970 971 972 973 | m32r*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) | | | 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 | m32r*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else |
︙ | ︙ | |||
1281 1282 1283 1284 1285 1286 1287 | echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown | | | 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 | echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ |
︙ | ︙ | |||
1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 | DS/*:UNIX_System_V:*:*) echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo "$UNAME_MACHINE"-unknown-plan9 exit ;; | > | 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 | DS/*:UNIX_System_V:*:*) echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. # shellcheck disable=SC2154 if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo "$UNAME_MACHINE"-unknown-plan9 exit ;; |
︙ | ︙ | |||
1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 | exit ;; x86_64:VMkernel:*:*) echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. | > > > | 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 | exit ;; x86_64:VMkernel:*:*) echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; *:Unleashed:*:*) echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" exit ;; esac echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. |
︙ | ︙ |
Modified build-aux/config.sub from [0f298c8265] to [f6ee861ee1].
1 2 | #! /bin/sh # Configuration validation subroutine script. | | | | 1 2 3 4 5 6 7 8 9 10 11 12 | #! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2019 Free Software Foundation, Inc. timestamp='2019-01-05' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but |
︙ | ︙ | |||
63 64 65 66 67 68 69 | -v, --version print version number, then exit Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.sub ($timestamp) | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | -v, --version print version number, then exit Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.sub ($timestamp) Copyright 1992-2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." |
︙ | ︙ | |||
85 86 87 88 89 90 91 | --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) | | > > > > > | > > > > > > > > > > > | > | | | | | | | > | < | | > | < | | > > > > > > > > > | > > > > > > > | | > > > > > > > > > > > > | | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < > > > | > > > | > > > > > > > | > | > > | < < | < < < < > | > > > > > > | > | > > > > > > > > | > > > > > | | > > > > > > > > > > > > > > > > > > > > | > | > > > > > > > > > > | > | | > > > > > > > > > > | > > > > > > > > > > > > | > | > > | > | > > | > > > > > > > > > > | > > > > > > | > | > > > > > > | > > > | > > | > | > > | > > > | | > > > > > > > > > > > > > > > > > > | > > > | > > > > > > | > | | > | > > | > | | > | > > | > | > > > > > > > > > | | > > > > > > | > | > > > > | < > > > > | > | > > > > > > > > | < > > > > > > > > | > | > > > > | > > > > > | > > > > > > | > | > > > > > > | > > | > | > > | > > > > > > > | > > > > > > | > | < > | > | > > > > > > | > > | > | > > > > | > | | | > > > > > > > > > > > > > | | > > | > > > | | | > > > > | > | > > > > > > | > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | > > > > | | | > > | | | < | > | < > | | > > | < < | | > | > > > > | > > | > > > | > > > | > > | < < | | > | | < > > | | | | > | > | | > | > > | > | > > > > > > > > > | < | | > | | | < | < < < > | | < < | > | | | > | > > | > > > > > > > > > > > > > > | | < > | > | < > | < | | < | > | > > | > > > > > > > > > | < > > > > | < > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > | > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > | > > | < < | < < < > | | < < < < < | < | < < | < | > < | > | < < > | > | > > > > > | | < < < < < < < | < < < < < < < < < > > | < < < < < < | | | | | | | | | | > | < | | < < < < < < < < < < < < > | < < < | > > | < > | < | > | | > | < < < < < | < < < < < > | < < > > > > > | < | < < < < | > < < < | | | | < > > | | | < < < | < | < < < | < < < < < < < | | < < > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < < < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < | | < < | < < < < < < < < < < < | | | < | | < | | > | > | < < < > | < > | < < < | < < < | | | | | | < | | | < < < < < < > | < | < < < | < < < < < | | < < < | > | < | < > | < < < | > | | < < < | > < < < > > < | | | < < < < | | | < < < > | | < | | < | < < < < | < < < | < < < > | > | > | > | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < | < | | < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | > > | | < > | | | | | | > > > | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > | | | | | < < < | | | > > > > > > > > > > > > > > > > > > | | < < < < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > < < | | | | | | | | > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > | | < | | | | | | | | | | | | > > > | | | | | | | | | | < | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 | --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type # shellcheck disable=SC2162 IFS="-" read field1 field2 field3 field4 <<EOF $1 EOF # Separate into logical components for further validation case $1 in *-*-*-*-*) echo Invalid configuration \`"$1"\': more than four components >&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \ | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 os=$maybe_os ;; android-linux) basic_machine=$field1-unknown os=linux-android ;; *) basic_machine=$field1-$field2 os=$field3 ;; esac ;; *-*) # A lone config we happen to match not fitting any pattern case $field1-$field2 in decstation-3100) basic_machine=mips-dec os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ | unicom* | ibm* | next | hp | isi* | apollo | altos* \ | convergent* | ncr* | news | 32* | 3600* | 3100* \ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ | ultra | tti* | harris | dolphin | highlevel | gould \ | cbm | ns | masscomp | apple | axis | knuth | cray \ | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 os= ;; *) basic_machine=$field1 os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc os=bsd ;; a29khif) basic_machine=a29k-amd os=udi ;; adobe68k) basic_machine=m68010-adobe os=scout ;; alliant) basic_machine=fx80-alliant os= ;; altos | altos3068) basic_machine=m68k-altos os= ;; am29k) basic_machine=a29k-none os=bsd ;; amdahl) basic_machine=580-amdahl os=sysv ;; amiga) basic_machine=m68k-unknown os= ;; amigaos | amigados) basic_machine=m68k-unknown os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=sysv4 ;; apollo68) basic_machine=m68k-apollo os=sysv ;; apollo68bsd) basic_machine=m68k-apollo os=bsd ;; aros) basic_machine=i386-pc os=aros ;; aux) basic_machine=m68k-apple os=aux ;; balance) basic_machine=ns32k-sequent os=dynix ;; blackfin) basic_machine=bfin-unknown os=linux ;; cegcc) basic_machine=arm-unknown os=cegcc ;; convex-c1) basic_machine=c1-convex os=bsd ;; convex-c2) basic_machine=c2-convex os=bsd ;; convex-c32) basic_machine=c32-convex os=bsd ;; convex-c34) basic_machine=c34-convex os=bsd ;; convex-c38) basic_machine=c38-convex os=bsd ;; cray) basic_machine=j90-cray os=unicos ;; crds | unos) basic_machine=m68k-crds os= ;; da30) basic_machine=m68k-da30 os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec os= ;; delta88) basic_machine=m88k-motorola os=sysv3 ;; dicos) basic_machine=i686-pc os=dicos ;; djgpp) basic_machine=i586-pc os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=ose ;; gmicro) basic_machine=tron-gmicro os=sysv ;; go32) basic_machine=i386-pc os=go32 ;; h8300hms) basic_machine=h8300-hitachi os=hms ;; h8300xray) basic_machine=h8300-hitachi os=xray ;; h8500hms) basic_machine=h8500-hitachi os=hms ;; harris) basic_machine=m88k-harris os=sysv3 ;; hp300) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=bsd ;; hp300hpux) basic_machine=m68k-hp os=hpux ;; hppaosf) basic_machine=hppa1.1-hp os=osf ;; hppro) basic_machine=hppa1.1-hp os=proelf ;; i386mach) basic_machine=i386-mach os=mach ;; vsta) basic_machine=i386-pc os=vsta ;; isi68 | isi) basic_machine=m68k-isi os=sysv ;; m68knommu) basic_machine=m68k-unknown os=linux ;; magnum | m3230) basic_machine=mips-mips os=sysv ;; merlin) basic_machine=ns32k-utek os=sysv ;; mingw64) basic_machine=x86_64-pc os=mingw64 ;; mingw32) basic_machine=i686-pc os=mingw32 ;; mingw32ce) basic_machine=arm-unknown os=mingw32ce ;; monitor) basic_machine=m68k-rom68k os=coff ;; morphos) basic_machine=powerpc-unknown os=morphos ;; moxiebox) basic_machine=moxie-unknown os=moxiebox ;; msdos) basic_machine=i386-pc os=msdos ;; msys) basic_machine=i686-pc os=msys ;; mvs) basic_machine=i370-ibm os=mvs ;; nacl) basic_machine=le32-unknown os=nacl ;; ncr3000) basic_machine=i486-ncr os=sysv4 ;; netbsd386) basic_machine=i386-pc os=netbsd ;; netwinder) basic_machine=armv4l-rebel os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=newsos ;; news1000) basic_machine=m68030-sony os=newsos ;; necv70) basic_machine=v70-nec os=sysv ;; nh3000) basic_machine=m68k-harris os=cxux ;; nh[45]000) basic_machine=m88k-harris os=cxux ;; nindy960) basic_machine=i960-intel os=nindy ;; mon960) basic_machine=i960-intel os=mon960 ;; nonstopux) basic_machine=mips-compaq os=nonstopux ;; os400) basic_machine=powerpc-ibm os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=ose ;; os68k) basic_machine=m68k-none os=os68k ;; paragon) basic_machine=i860-intel os=osf ;; parisc) basic_machine=hppa-unknown os=linux ;; pw32) basic_machine=i586-unknown os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=rdos ;; rdos32) basic_machine=i386-pc os=rdos ;; rom68k) basic_machine=m68k-rom68k os=coff ;; sa29200) basic_machine=a29k-amd os=udi ;; sei) basic_machine=mips-sei os=seiux ;; sequent) basic_machine=i386-sequent os= ;; sps7) basic_machine=m68k-bull os=sysv2 ;; st2000) basic_machine=m68k-tandem os= ;; stratus) basic_machine=i860-stratus os=sysv4 ;; sun2) basic_machine=m68000-sun os= ;; sun2os3) basic_machine=m68000-sun os=sunos3 ;; sun2os4) basic_machine=m68000-sun os=sunos4 ;; sun3) basic_machine=m68k-sun os= ;; sun3os3) basic_machine=m68k-sun os=sunos3 ;; sun3os4) basic_machine=m68k-sun os=sunos4 ;; sun4) basic_machine=sparc-sun os= ;; sun4os3) basic_machine=sparc-sun os=sunos3 ;; sun4os4) basic_machine=sparc-sun os=sunos4 ;; sun4sol2) basic_machine=sparc-sun os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun os= ;; sv1) basic_machine=sv1-cray os=unicos ;; symmetry) basic_machine=i386-sequent os=dynix ;; t3e) basic_machine=alphaev5-cray os=unicos ;; t90) basic_machine=t90-cray os=unicos ;; toad1) basic_machine=pdp10-xkl os=tops20 ;; tpf) basic_machine=s390x-ibm os=tpf ;; udi29k) basic_machine=a29k-amd os=udi ;; ultra3) basic_machine=a29k-nyu os=sym1 ;; v810 | necv810) basic_machine=v810-nec os=none ;; vaxv) basic_machine=vax-dec os=sysv ;; vms) basic_machine=vax-dec os=vms ;; vxworks960) basic_machine=i960-wrs os=vxworks ;; vxworks68) basic_machine=m68k-wrs os=vxworks ;; vxworks29k) basic_machine=a29k-wrs os=vxworks ;; xbox) basic_machine=i686-pc os=mingw32 ;; ymp) basic_machine=ymp-cray os=unicos ;; *) basic_machine=$1 os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) cpu=m68k vendor=motorola ;; dpx2*) cpu=m68k vendor=bull os=sysv3 ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi os=${os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray os=${os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $os in irix*) ;; *) os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony os=newsos ;; next | m*-next) cpu=m68k vendor=next case $os in nextstep* ) ;; ns2*) os=nextstep2 ;; *) os=nextstep3 ;; esac ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; psp) cpu=mipsallegrexel vendor=psp ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde os=${os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) # shellcheck disable=SC2162 IFS="-" read cpu vendor <<EOF $basic_machine EOF ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) cpu=$basic_machine vendor=pc ;; # These rules are duplicated from below for sake of the special case above; # i.e. things that normalized to x86 arches should also default to "pc" pc98) cpu=i386 vendor=pc ;; x64 | amd64) cpu=x86_64 vendor=pc ;; # Recognize the basic CPU types without company name. *) cpu=$basic_machine vendor=unknown ;; esac unset -v basic_machine # Decode basic machines in the full and proper CPU-Company form. case $cpu-$vendor in # Here we handle the default manufacturer of certain CPU types in canonical form. It is in # some cases the only manufacturer, in others, it is the most popular. craynv-unknown) vendor=cray os=${os:-unicosmp} ;; c90-unknown | c90-cray) vendor=cray os=${os:-unicos} ;; fx80-unknown) vendor=alliant ;; romp-unknown) vendor=ibm ;; mmix-unknown) vendor=knuth ;; microblaze-unknown | microblazeel-unknown) vendor=xilinx ;; rs6000-unknown) vendor=ibm ;; vax-unknown) vendor=dec ;; pdp11-unknown) vendor=dec ;; we32k-unknown) vendor=att ;; cydra-unknown) vendor=cydrome ;; i370-ibm*) vendor=ibm ;; orion-unknown) vendor=highlevel ;; xps-unknown | xps100-unknown) cpu=xps100 vendor=honeywell ;; # Here we normalize CPU types with a missing or matching vendor dpx20-unknown | dpx20-bull) cpu=rs6000 vendor=bull os=${os:-bosx} ;; # Here we normalize CPU types irrespective of the vendor amd64-*) cpu=x86_64 ;; blackfin-*) cpu=bfin os=linux ;; c54x-*) cpu=tic54x ;; c55x-*) cpu=tic55x ;; c6x-*) cpu=tic6x ;; e500v[12]-*) cpu=powerpc os=$os"spe" ;; mips3*-*) cpu=mips64 ;; ms1-*) cpu=mt ;; m68knommu-*) cpu=m68k os=linux ;; m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) cpu=s12z ;; openrisc-*) cpu=or32 ;; parisc-*) cpu=hppa os=linux ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 ;; pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) cpu=i686 ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) cpu=i686 ;; pentium4-*) cpu=i786 ;; pc98-*) cpu=i386 ;; ppc-* | ppcbe-*) cpu=powerpc ;; ppcle-* | powerpclittle-*) cpu=powerpcle ;; ppc64-*) cpu=powerpc64 ;; ppc64le-* | powerpc64little-*) cpu=powerpc64le ;; sb1-*) cpu=mipsisa64sb1 ;; sb1el-*) cpu=mipsisa64sb1el ;; sh5e[lb]-*) cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` ;; spur-*) cpu=spur ;; strongarm-* | thumb-*) cpu=arm ;; tx39-*) cpu=mipstx39 ;; tx39el-*) cpu=mipstx39el ;; x64-*) cpu=x86_64 ;; xscale-* | xscalee[bl]-*) cpu=`echo "$cpu" | sed 's/^xscale/arm/'` ;; # Recognize the canonical CPU Types that limit and/or modify the # company names they are paired with. cr16-*) os=${os:-elf} ;; crisv32-* | etraxfs*-*) cpu=crisv32 vendor=axis ;; cris-* | etrax*-*) cpu=cris vendor=axis ;; crx-*) os=${os:-elf} ;; neo-tandem) cpu=neo vendor=tandem ;; nse-tandem) cpu=nse vendor=tandem ;; nsr-tandem) cpu=nsr vendor=tandem ;; nsv-tandem) cpu=nsv vendor=tandem ;; nsx-tandem) cpu=nsx vendor=tandem ;; s390-*) cpu=s390 vendor=ibm ;; s390x-*) cpu=s390x vendor=ibm ;; tile*-*) os=${os:-linux-gnu} ;; *) # Recognize the canonical CPU types that are allowed with any # company name. case $cpu in 1750a | 580 \ | a29k \ | aarch64 | aarch64_be | arm64 \ | abacus \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ | alphapca5[67] | alpha64pca5[67] \ | am33_2.0 \ | amdgcn \ | arc | arceb \ | arm | arm[lb]e | arme[lb] | armv* \ | avr | avr32 \ | asmjs \ | ba \ | be32 | be64 \ | bfin | bs2000 \ | c[123]* | c30 | [cjt]90 | c4x \ | c8051 | clipper | craynv | csky | cydra \ | d10v | d30v | dlx | dsp16xx \ | e2k | elxsi | epiphany \ | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ | h8300 | h8500 \ | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i*86 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle \ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ | m88110 | m88k | maxq | mb | mcore | mep | metag \ | microblaze | microblazeel \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64eb | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mmix \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nfp \ | nios | nios2 | nios2eb | nios2el \ | none | np1 | ns16k | ns32k | nvptx \ | open8 \ | or1k* \ | or32 \ | orion \ | picochip \ | pdp10 | pdp11 | pj | pjl | pn | power \ | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ | pru \ | pyramid \ | riscv | riscv32 | riscv64 \ | rl78 | romp | rs6000 | rx \ | score \ | sh | shl \ | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ | spu \ | tahoe \ | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ | tron \ | ubicom32 \ | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ | vax \ | visium \ | w65 | wasm32 \ | we32k \ | x86 | x86_64 | xc16x | xgate | xps100 \ | xstormy16 | xtensa* \ | ymp \ | z8k | z80) ;; *) echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x$os != x ] then case $os in # First match some system type aliases that might get confused # with valid system types. # solaris* is a basic system type, with this one exception. auroraux) os=auroraux ;; bluegene*) os=cnk ;; solaris1 | solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; solaris) os=solaris2 ;; unixware*) os=sysv4.2uw ;; gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # es1800 is here to avoid being matched by es* (a different OS) es1800*) os=ose ;; # Some version numbers need modification chorusos*) os=chorusos ;; isc) os=isc2.2 ;; sco6) os=sco5v6 ;; sco5) os=sco3.2v5 ;; sco4) os=sco3.2v4 ;; sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` ;; sco3.2v[4-9]* | sco5v6*) # Don't forget version if it is 3.2v4 or newer. ;; scout) # Don't match below ;; sco*) os=sco3.2v2 ;; psos*) os=psos ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. # sysv* is not here because it comes later, after sysvr4. gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\ | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ | sym* | kopensolaris* | plan9* \ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ | aos* | aros* | cloudabi* | sortix* \ | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ | knetbsd* | mirbsd* | netbsd* \ | bitrig* | openbsd* | solidbsd* | libertybsd* \ | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \ | chorusrdb* | cegcc* | glidix* \ | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \ | linux-newlib* | linux-musl* | linux-uclibc* \ | uxpv* | beos* | mpeix* | udk* | moxiebox* \ | interix* | uwin* | mks* | rhapsody* | darwin* \ | openstep* | oskit* | conix* | pw32* | nonstopux* \ | storm-chaos* | tops10* | tenex* | tops20* | its* \ | os2* | vos* | palmos* | uclinux* | nucleus* \ | morphos* | superux* | rtmk* | windiss* \ | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ | skyos* | haiku* | rdos* | toppers* | drops* | es* \ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | midnightbsd* | amdhsa* | unleashed* | emscripten*) # Remember, each alternative MUST END IN *, to match a version number. ;; qnx*) case $cpu in x86 | i*86) ;; *) os=nto-$os ;; esac ;; hiux*) os=hiuxwe2 ;; nto-qnx*) ;; nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; sim | xray | os68k* | v88r* \ | windows* | osx | abug | netware* | os9* \ | macos* | mpw* | magic* | mmixware* | mon960* | lnews*) ;; linux-dietlibc) os=linux-dietlibc ;; linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; lynx*178) os=lynxos178 ;; lynx*5) os=lynxos5 ;; lynx*) os=lynxos ;; mac*) os=`echo "$os" | sed -e 's|mac|macos|'` ;; opened*) os=openedition ;; os400*) os=os400 ;; sunos5*) os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; sunos6*) os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; wince*) os=wince ;; utek*) os=bsd ;; dynix*) os=bsd ;; acis*) os=aos ;; atheos*) os=atheos ;; syllable*) os=syllable ;; 386bsd) os=bsd ;; ctix* | uts*) os=sysv ;; nova*) os=rtmk-nova ;; ns2) os=nextstep2 ;; nsk*) os=nsk ;; # Preserve the version number of sinix5. sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; sinix*) os=sysv4 ;; tpf*) os=tpf ;; triton*) os=sysv3 ;; oss*) os=sysv3 ;; svr4*) os=sysv4 ;; svr3) os=sysv3 ;; sysvr4) os=sysv4 ;; # This must come after sysvr4. sysv*) ;; ose*) os=ose ;; *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) os=mint ;; zvmoe) os=zvmoe ;; dicos*) os=dicos ;; pikeos*) # Until real need of OS specific support for # particular features comes up, bare metal # configurations are quite functional. case $cpu in arm*) os=eabi ;; *) os=elf ;; esac ;; nacl*) ;; ios) ;; none) ;; *-eabi) ;; *) echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $cpu-$vendor in score-*) os=elf ;; spu-*) os=elf ;; *-acorn) os=riscix1.2 ;; arm*-rebel) os=linux ;; arm*-semi) os=aout ;; c4x-* | tic4x-*) os=coff ;; c8051-*) os=elf ;; clipper-intergraph) os=clix ;; hexagon-*) os=elf ;; tic54x-*) os=coff ;; tic55x-*) os=coff ;; tic6x-*) os=coff ;; # This must come before the *-dec entry. pdp10-*) os=tops20 ;; pdp11-*) os=none ;; *-dec | vax-*) os=ultrix4.2 ;; m68*-apollo) os=domain ;; i386-sun) os=sunos4.0.2 ;; m68000-sun) os=sunos3 ;; m68*-cisco) os=aout ;; mep-*) os=elf ;; mips*-cisco) os=elf ;; mips*-*) os=elf ;; or32-*) os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=sysv3 ;; sparc-* | *-sun) os=sunos4.1.1 ;; pru-*) os=elf ;; *-be) os=beos ;; *-ibm) os=aix ;; *-knuth) os=mmixware ;; *-wec) os=proelf ;; *-winbond) os=proelf ;; *-oki) os=proelf ;; *-hp) os=hpux ;; *-hitachi) os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=sysv ;; *-cbm) os=amigaos ;; *-dg) os=dgux ;; *-dolphin) os=sysv3 ;; m68k-ccur) os=rtu ;; m88k-omron*) os=luna ;; *-next) os=nextstep ;; *-sequent) os=ptx ;; *-crds) os=unos ;; *-ns) os=genix ;; i370-*) os=mvs ;; *-gould) os=sysv ;; *-highlevel) os=bsd ;; *-encore) os=bsd ;; *-sgi) os=irix ;; *-siemens) os=sysv4 ;; *-masscomp) os=rtu ;; f30[01]-fujitsu | f700-fujitsu) os=uxpv ;; *-rom68k) os=coff ;; *-*bug) os=coff ;; *-apple) os=macos ;; *-atari*) os=mint ;; *-wrs) os=vxworks ;; *) os=none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $os in riscix*) vendor=acorn ;; sunos*) vendor=sun ;; cnk*|-aix*) vendor=ibm ;; beos*) vendor=be ;; hpux*) vendor=hp ;; mpeix*) vendor=hp ;; hiux*) vendor=hitachi ;; unos*) vendor=crds ;; dgux*) vendor=dg ;; luna*) vendor=omron ;; genix*) vendor=ns ;; clix*) vendor=intergraph ;; mvs* | opened*) vendor=ibm ;; os400*) vendor=ibm ;; ptx*) vendor=sequent ;; tpf*) vendor=ibm ;; vxsim* | vxworks* | windiss*) vendor=wrs ;; aux*) vendor=apple ;; hms*) vendor=hitachi ;; mpw* | macos*) vendor=apple ;; *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) vendor=atari ;; vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor-$os" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: |
Modified build-aux/install-sh from [4fa2988af1] to [0170726bd8].
1 | #!/bin/sh | < | > | > | > | < < | | | < < | < < | < < < < < < < < < < | | < > > > < < < | | < | < | | < < | < > > | | | | | < < | | < | | > | | | < | < > | | | | | < | < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | | | | > > > | | | | < < | < < < < | | > | | | < > | < < < < < < > | | < < | | < | > < < | | | | > > | < > | < < | | | < < < < > | > | > | < | | > | > > | < < | < | < < < < < < < < < < < < < < < < < < < < | | | | < < | < < < < < < | < | < > | < > > | < < < < < < | < | > | < | > > > | | < | | | < < | > | | | < < < < < < < < < < < | | > > | | | < < | > | | < < | | | | < | < < < < < < < < > < < < < < < < < < | < < | < | < | > > | | > > | | < < < | < > | > | | | > > | < < < < < < < < < < < < < | > | < > > | | > | < | < < < > > > < < < < < < < | | < < < > > | < < | < < < > | | | | < | < | < < | < | | | | < | < > | | < < < < < | | < < | < | < < < < < < < < < < < < > < | < | > > | | > > | < | < < < < < > > > > > | | < < < < < < < < < < < < < < | | < | > | < < > > > | < < < > > > > | | | | > > > | < < < < < < | < < | < | < < | | < < < < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | #!/bin/sh # # $NetBSD: install-sh.in,v 1.6 2012/01/11 13:07:31 hans Exp $ # This script now also installs multiple files, but might choke on installing # multiple files with spaces in the file names. # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. awkprog="${AWKPROG-awk}" mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" instcmd="$cpprog" instflags="" pathcompchmodcmd="$chmodprog 755" chmodcmd="$chmodprog 755" chowncmd="" chgrpcmd="" stripcmd="" stripflags="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" msrc="" dst="" dir_arg="" suffix="" suffixfmt="" while [ x"$1" != x ]; do case $1 in -b) suffix=".old" shift continue;; -B) suffixfmt="$2" shift shift continue;; -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -m*) chmodcmd="$chmodprog ${1#-m}" shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -S) stripcmd="$stripprog" stripflags="-S $2 $stripflags" shift shift continue;; -p) instflags="-p" shift continue;; *) if [ x"$msrc" = x ] then msrc="$dst" else msrc="$msrc $dst" fi src="$dst" dst="$1" shift continue;; esac done if [ x"$dir_arg" = x ] then dstisfile="" if [ ! -d "$dst" ] then if [ x"$msrc" = x"$src" ] then dstisfile=true else echo "install: destination is not a directory" exit 1 fi fi else msrc="$msrc $dst" fi if [ x"$msrc" = x ] then echo "install: no destination specified" exit 1 fi for srcarg in $msrc; do if [ x"$dir_arg" != x ]; then dstarg="$srcarg" else dstarg="$dst" # Waiting for this to be detected by the "$instcmd $srcarg $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f "$srcarg" ] then doinst="$instcmd $instflags" elif [ -d "$srcarg" ] then echo "install: $srcarg: not a regular file" exit 1 elif [ "$srcarg" = "/dev/null" ] then doinst="$cpprog" else echo "install: $srcarg does not exist" exit 1 fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d "$dstarg" ] then dstarg="$dstarg"/`basename "$srcarg"` fi fi ## this sed command emulates the dirname command dstdir=`echo "$dstarg" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $doit $mkdirprog "${pathcomp}" if [ x"$chowncmd" != x ]; then $doit $chowncmd "${pathcomp}"; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "${pathcomp}"; else true ; fi && if [ x"$pathcompchmodcmd" != x ]; then $doit $pathcompchmodcmd "${pathcomp}"; else true ; fi else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then if [ -d "$dstarg" ]; then true else $doit $mkdirprog "$dstarg" && if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dstarg"; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dstarg"; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dstarg"; else true ; fi fi else if [ x"$dstisfile" = x ] then file=$srcarg else file=$dst fi dstfile=`basename "$file"` dstfinal="$dstdir/$dstfile" # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Make a backup file name in the proper directory. case x$suffixfmt in *%*) suffix=`echo x | $awkprog -v bname="$dstfinal" -v fmt="$suffixfmt" ' { cnt = 0; do { sfx = sprintf(fmt, cnt++); name = bname sfx; } while (system("test -f " name) == 0); print sfx; }' -`;; x) ;; *) suffix="$suffixfmt";; esac dstbackup="$dstfinal$suffix" # Move or copy the file name to the temp name $doit $doinst $srcarg "$dsttmp" && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripflags "$dsttmp"; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else true;fi && # Now rename the file to the real destination. if [ x"$suffix" != x ] && [ -f "$dstfinal" ] then $doit $mvcmd "$dstfinal" "$dstbackup" else $doit $rmcmd -f "$dstfinal" fi && $doit $mvcmd "$dsttmp" "$dstfinal" fi done && exit 0 |
Modified build-aux/m4/buildsys.m4 from [74391b1263] to [824bccf73b].
1 2 | dnl dnl Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017, | | | 1 2 3 4 5 6 7 8 9 10 | dnl dnl Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017, dnl 2018, 2020, 2021 dnl Jonathan Schleifer <js@nil.im> dnl dnl https://fossil.nil.im/buildsys dnl dnl Permission to use, copy, modify, and/or distribute this software for any dnl purpose with or without fee is hereby granted, provided that the above dnl copyright notice and this permission notice is present in all copies. |
︙ | ︙ | |||
22 23 24 25 26 27 28 29 | dnl POSSIBILITY OF SUCH DAMAGE. dnl AC_DEFUN([BUILDSYS_INIT], [ AC_REQUIRE([AC_CANONICAL_BUILD]) AC_REQUIRE([AC_CANONICAL_HOST]) case "$build_os" in | > > > | | | | | | | > > > > > > > > > > > > > > > | > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | dnl POSSIBILITY OF SUCH DAMAGE. dnl 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) ;; esac ;; esac AC_PROG_INSTALL case "$INSTALL" in ./build-aux/install-sh*) INSTALL="$PWD/$INSTALL" ;; esac AC_CONFIG_COMMANDS_PRE([ AS_IF([test x"$GCC" = x"yes"], [AC_SUBST(DEP_CFLAGS, '-MD -MF $${out%.o}.dep')]) AS_IF([test x"$GXX" = x"yes"], [AC_SUBST(DEP_CXXFLAGS, '-MD -MF $${out%.o}.dep')]) AS_IF([test x"$GOBJC" = x"yes"], [AC_SUBST(DEP_OBJCFLAGS, '-MD -MF $${out%.o}.dep')]) AS_IF([test x"$GOBJCXX" = x"yes"], [AC_SUBST(DEP_OBJCXXFLAGS, '-MD -MF $${out%.o}.dep')]) AC_SUBST(AMIGA_LIB_CFLAGS) AC_SUBST(AMIGA_LIB_LDFLAGS) case "$build_os" in morphos*) dnl Don't use tput on MorphOS: The colored output is dnl quite unreadable and in some MorphOS versions the dnl output from tput is not 8-bit safe, with awk (for dnl AC_SUBST) failing as a result. ;; *) AC_PATH_PROG(TPUT, tput) ;; esac AS_IF([test x"$TPUT" != x""], [ if x=$($TPUT el 2>/dev/null); then AC_SUBST(TERM_EL, "$x") else AC_SUBST(TERM_EL, "$($TPUT ce 2>/dev/null)") fi |
︙ | ︙ | |||
108 109 110 111 112 113 114 | fi ]) ]) ]) AC_DEFUN([BUILDSYS_CHECK_IOS], [ case "$host_os" in | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > | | | | | | | | | | | | | | | | | > > | | | | | | | | | | | | | | | | | < | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | > > | | | | | | | | | | > | | | | | | | | | | > | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | fi ]) ]) ]) AC_DEFUN([BUILDSYS_CHECK_IOS], [ case "$host_os" in darwin*) AC_MSG_CHECKING(whether host is iOS) AC_EGREP_CPP(yes, [ #include <TargetConditionals.h> #if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \ (defined(TARGET_OS_SIMULATOR) && \ TARGET_OS_SIMULATOR) yes #endif ], [ host_is_ios="yes" ], [ host_is_ios="no" ]) AC_MSG_RESULT($host_is_ios) ;; esac ]) AC_DEFUN([BUILDSYS_PROG_IMPLIB], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_MSG_CHECKING(whether we need an implib) case "$host_os" in cygwin* | mingw*) AC_MSG_RESULT(yes) PROG_IMPLIB_NEEDED='yes' PROG_IMPLIB_LDFLAGS='-Wl,--export-all-symbols,--out-implib,lib${PROG}.a' ;; *) AC_MSG_RESULT(no) PROG_IMPLIB_NEEDED='no' PROG_IMPLIB_LDFLAGS='' ;; esac AC_SUBST(PROG_IMPLIB_NEEDED) AC_SUBST(PROG_IMPLIB_LDFLAGS) ]) AC_DEFUN([BUILDSYS_SHARED_LIB], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([BUILDSYS_CHECK_IOS]) AC_MSG_CHECKING(for shared library system) case "$host" in *-*-darwin*) AC_MSG_RESULT(Darwin) LIB_CFLAGS='-fPIC -DPIC' LIB_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}' LIB_LDFLAGS_INSTALL_NAME='-Wl,-install_name,${libdir}/$${out%.dylib}.${LIB_MAJOR}.dylib' LIB_PREFIX='lib' LIB_SUFFIX='.dylib' AS_IF([test x"$enable_rpath" != x"no"], [ LDFLAGS_RPATH='-Wl,-rpath,${libdir}' ]) PLUGIN_CFLAGS='-fPIC -DPIC' PLUGIN_LDFLAGS='-bundle ${PLUGIN_LDFLAGS_BUNDLE_LOADER}' PLUGIN_SUFFIX='.bundle' AS_IF([test x"$host_is_ios" = x"yes"], [ LINK_PLUGIN='rm -fr $$out && ${MKDIR_P} $$out && if test -f Info.plist; then ${INSTALL} -m 644 Info.plist $$out/Info.plist; fi && ${LD} -o $$out/$${out%${PLUGIN_SUFFIX}} ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS} && ${CODESIGN} -fs ${CODESIGN_IDENTITY} --timestamp=none $$out' ], [ LINK_PLUGIN='rm -fr $$out && ${MKDIR_P} $$out/Contents/MacOS && if test -f Info.plist; then ${INSTALL} -m 644 Info.plist $$out/Contents/Info.plist; fi && ${LD} -o $$out/Contents/MacOS/$${out%${PLUGIN_SUFFIX}} ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS} && ${CODESIGN} -fs ${CODESIGN_IDENTITY} --timestamp=none $$out' ]) INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i' UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib' INSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i && cp -R $$i ${DESTDIR}${plugindir}/' UNINSTALL_PLUGIN='&& rm -fr ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; *-*-mingw* | *-*-cygwin*) AC_MSG_RESULT(MinGW / Cygwin) LIB_CFLAGS='' LIB_LDFLAGS='-shared -Wl,--export-all-symbols' 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 -Wl,--export-all-symbols' PLUGIN_SUFFIX='.dll' LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}' INSTALL_LIB='&& ${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i && ${INSTALL} -m 755 lib$${i%${LIB_SUFFIX}}.dll.a ${DESTDIR}${libdir}/lib$${i%${LIB_SUFFIX}}.dll.a' UNINSTALL_LIB='&& rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/lib$${i%${LIB_SUFFIX}}.dll.a' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='${SHARED_LIB}.a ${SHARED_LIB_NOINST}.a' ;; *-*-openbsd* | *-*-mirbsd*) AC_MSG_RESULT(OpenBSD) LIB_CFLAGS='-fPIC -DPIC' LIB_LDFLAGS='-shared' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='lib' LIB_SUFFIX='.so.${LIB_MAJOR}.${LIB_MINOR}' AS_IF([test x"$enable_rpath" != x"no"], [ LDFLAGS_RPATH='-Wl,-rpath,${libdir}' ]) PLUGIN_CFLAGS='-fPIC -DPIC' PLUGIN_LDFLAGS='-shared' PLUGIN_SUFFIX='.so' LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}' INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i' UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; *-*-solaris*) AC_MSG_RESULT(Solaris) LIB_CFLAGS='-fPIC -DPIC' LIB_LDFLAGS='-shared -Wl,-soname=$$out.${LIB_MAJOR}.${LIB_MINOR}' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='lib' LIB_SUFFIX='.so' AS_IF([test x"$enable_rpath" != x"no"], [ LDFLAGS_RPATH='-Wl,-rpath,${libdir}' ]) PLUGIN_CFLAGS='-fPIC -DPIC' PLUGIN_LDFLAGS='-shared' PLUGIN_SUFFIX='.so' LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}' INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR} && rm -f ${DESTDIR}${libdir}/$$i && ${LN_S} $$i.${LIB_MAJOR}.${LIB_MINOR} ${DESTDIR}${libdir}/$$i' UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; *-*-android*) AC_MSG_RESULT(Android) LIB_CFLAGS='-fPIC -DPIC' LIB_LDFLAGS='-shared -Wl,-soname=$$out.${LIB_MAJOR}' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='lib' LIB_SUFFIX='.so' PLUGIN_CFLAGS='-fPIC -DPIC' PLUGIN_LDFLAGS='-shared' PLUGIN_SUFFIX='.so' LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}' INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0 && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i' UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; hppa*-*-hpux*) AC_MSG_RESULT([HP-UX (PA-RISC)]) LIB_CFLAGS='-fPIC -DPIC' LIB_LDFLAGS='-shared -Wl,+h,$$out' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='lib' LIB_SUFFIX='.${LIB_MAJOR}' LINK_LIB='&& rm -f $${out%%.*}.sl && ${LN_S} $$out $${out%%.*}.sl' AS_IF([test x"$enable_rpath" != x"no"], [ LDFLAGS_RPATH='-Wl,+b,${libdir}' ]) PLUGIN_CFLAGS='-fPIC -DPIC' PLUGIN_LDFLAGS='-shared' PLUGIN_SUFFIX='.sl' LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}' INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i && ${LN_S} -f $$i ${DESTDIR}${libdir}/$${i%%.*}.sl' UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%%.*}.sl' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; ia64*-*-hpux*) AC_MSG_RESULT([HP-UX (Itanium)]) LIB_CFLAGS='-fPIC -DPIC' LIB_LDFLAGS='-shared -Wl,+h,$$out' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='lib' LIB_SUFFIX='.${LIB_MAJOR}' LINK_LIB='&& rm -f $${out%%.*}.so && ${LN_S} $$out $${out%%.*}.so' AS_IF([test x"$enable_rpath" != x"no"], [ LDFLAGS_RPATH='-Wl,+b,${libdir}' ]) PLUGIN_CFLAGS='-fPIC -DPIC' PLUGIN_LDFLAGS='-shared' PLUGIN_SUFFIX='.so' LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}' INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i && ${LN_S} -f $$i ${DESTDIR}${libdir}/$${i%%.*}.so' UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%%.*}.so' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; *) AC_MSG_RESULT(ELF) LIB_CFLAGS='-fPIC -DPIC' LIB_LDFLAGS='-shared -Wl,-soname=$$out.${LIB_MAJOR}' LIB_LDFLAGS_INSTALL_NAME='' LIB_PREFIX='lib' LIB_SUFFIX='.so' AS_IF([test x"$enable_rpath" != x"no"], [ LDFLAGS_RPATH='-Wl,-rpath,${libdir}' ]) PLUGIN_CFLAGS='-fPIC -DPIC' PLUGIN_LDFLAGS='-shared' PLUGIN_SUFFIX='.so' LINK_PLUGIN='${LD} -o $$out ${PLUGIN_OBJS} ${PLUGIN_OBJS_EXTRA} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}' INSTALL_LIB='&& ${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0 && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i' UNINSTALL_LIB='&& rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0' INSTALL_PLUGIN='&& ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i' UNINSTALL_PLUGIN='&& rm -f ${DESTDIR}${plugindir}/$$i' CLEAN_LIB='' ;; esac AC_SUBST(LIB_CFLAGS) AC_SUBST(LIB_LDFLAGS) AC_SUBST(LIB_LDFLAGS_INSTALL_NAME) AC_SUBST(LIB_PREFIX) AC_SUBST(LIB_SUFFIX) AC_SUBST(LINK_LIB) AC_SUBST(LDFLAGS_RPATH) AC_SUBST(PLUGIN_CFLAGS) AC_SUBST(PLUGIN_LDFLAGS) AC_SUBST(PLUGIN_SUFFIX) AC_SUBST(LINK_PLUGIN) AC_SUBST(INSTALL_LIB) AC_SUBST(UNINSTALL_LIB) AC_SUBST(INSTALL_PLUGIN) AC_SUBST(UNINSTALL_PLUGIN) AC_SUBST(CLEAN_LIB) ]) AC_DEFUN([BUILDSYS_FRAMEWORK], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([BUILDSYS_CHECK_IOS]) AC_REQUIRE([BUILDSYS_SHARED_LIB]) AC_CHECK_TOOL(CODESIGN, codesign) case "$host_os" in darwin*) AS_IF([test x"$host_is_ios" = x"yes"], [ FRAMEWORK_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}' FRAMEWORK_LDFLAGS_INSTALL_NAME='-Wl,-install_name,@executable_path/Frameworks/$$out/$${out%.framework}' ], [ FRAMEWORK_LDFLAGS='-dynamiclib -current_version ${LIB_MAJOR}.${LIB_MINOR} -compatibility_version ${LIB_MAJOR}' FRAMEWORK_LDFLAGS_INSTALL_NAME='-Wl,-install_name,@executable_path/../Frameworks/$$out/$${out%.framework}' ]) AC_SUBST(FRAMEWORK_LDFLAGS) AC_SUBST(FRAMEWORK_LDFLAGS_INSTALL_NAME) AC_SUBST(FRAMEWORK_LIBS) $1 ;; esac ]) |
Added build-aux/m4/pkg.m4 version [f7f00f7dea].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 | # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 11 (pkg-config-0.29.1) dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> 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 <http://pkg-config.freedesktop.org/>.])[]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 |
Modified buildsys.mk.in from [0dd86557eb] to [a085f99653].
1 2 | # # Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, | | | 1 2 3 4 5 6 7 8 9 10 | # # Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, # 2017, 2018, 2020, 2021 # Jonathan Schleifer <js@nil.im> # # https://fossil.nil.im/buildsys # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice is present in all copies. |
︙ | ︙ | |||
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | PROG_IMPLIB_LDFLAGS = @PROG_IMPLIB_LDFLAGS@ PROG_SUFFIX = @EXEEXT@ LIB_CFLAGS = @LIB_CFLAGS@ LIB_LDFLAGS = @LIB_LDFLAGS@ LIB_LDFLAGS_INSTALL_NAME = @LIB_LDFLAGS_INSTALL_NAME@ LIB_PREFIX = @LIB_PREFIX@ LIB_SUFFIX = @LIB_SUFFIX@ AMIGA_LIB_CFLAGS = @AMIGA_LIB_CFLAGS@ AMIGA_LIB_LDFLAGS = @AMIGA_LIB_LDFLAGS@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PLUGIN_SUFFIX = @PLUGIN_SUFFIX@ FRAMEWORK_LDFLAGS = @FRAMEWORK_LDFLAGS@ FRAMEWORK_LDFLAGS_INSTALL_NAME = @FRAMEWORK_LDFLAGS_INSTALL_NAME@ CODESIGN = @CODESIGN@ CODESIGN_IDENTITY ?= - CLEAN_LIB = @CLEAN_LIB@ DEP_ASFLAGS = @DEP_ASFLAGS@ DEP_CFLAGS = @DEP_CFLAGS@ DEP_CXXFLAGS = @DEP_CXXFLAGS@ DEP_OBJCFLAGS = @DEP_OBJCFLAGS@ | > > | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | PROG_IMPLIB_LDFLAGS = @PROG_IMPLIB_LDFLAGS@ PROG_SUFFIX = @EXEEXT@ LIB_CFLAGS = @LIB_CFLAGS@ LIB_LDFLAGS = @LIB_LDFLAGS@ LIB_LDFLAGS_INSTALL_NAME = @LIB_LDFLAGS_INSTALL_NAME@ LIB_PREFIX = @LIB_PREFIX@ LIB_SUFFIX = @LIB_SUFFIX@ LINK_LIB = @LINK_LIB@ AMIGA_LIB_CFLAGS = @AMIGA_LIB_CFLAGS@ AMIGA_LIB_LDFLAGS = @AMIGA_LIB_LDFLAGS@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PLUGIN_SUFFIX = @PLUGIN_SUFFIX@ FRAMEWORK_LDFLAGS = @FRAMEWORK_LDFLAGS@ FRAMEWORK_LDFLAGS_INSTALL_NAME = @FRAMEWORK_LDFLAGS_INSTALL_NAME@ FRAMEWORK_LIBS = @FRAMEWORK_LIBS@ CODESIGN = @CODESIGN@ CODESIGN_IDENTITY ?= - CLEAN_LIB = @CLEAN_LIB@ DEP_ASFLAGS = @DEP_ASFLAGS@ DEP_CFLAGS = @DEP_CFLAGS@ DEP_CXXFLAGS = @DEP_CXXFLAGS@ DEP_OBJCFLAGS = @DEP_OBJCFLAGS@ |
︙ | ︙ | |||
144 145 146 147 148 149 150 | ${DIR_ENTER}; \ ${MAKE} -s || exit $$?; \ ${DIR_LEAVE}; \ done depend: pre-depend : >.deps | | > | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | ${DIR_ENTER}; \ ${MAKE} -s || exit $$?; \ ${DIR_LEAVE}; \ done depend: pre-depend : >.deps for i in "" ${DEPS}; do \ test x"$$i" = x"" && continue; \ echo "-include \$${.CURDIR}/$$i" >>.deps; \ done pre-depend: ${PROG} ${PROG_NOINST}: ${EXT_DEPS} ${OBJS} ${OBJS_EXTRA} ${LINK_STATUS} |
︙ | ︙ | |||
178 179 180 181 182 183 184 | ${LINK_FAILED}; \ fi \ fi ${SHARED_LIB} ${SHARED_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LINK_STATUS} out="$@"; \ | | | 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | ${LINK_FAILED}; \ fi \ fi ${SHARED_LIB} ${SHARED_LIB_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LINK_STATUS} out="$@"; \ if ${LD} -o $@ ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LIB_LDFLAGS} ${LIB_LDFLAGS_INSTALL_NAME} ${LDFLAGS} ${LIBS} ${LINK_LIB}; then \ ${LINK_OK}; \ else \ ${LINK_FAILED}; \ fi ${FRAMEWORK} ${FRAMEWORK_NOINST}: ${EXT_DEPS} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${LINK_STATUS} |
︙ | ︙ | |||
205 206 207 208 209 210 211 | ${MAKE} -s copy-headers-into-framework || exit $$?; \ cd .. || exit 1; \ done if test x"${includesubdir}" = x"${COPY_HEADERS_IF_SUBDIR}"; then \ for i in "" ${INCLUDES}; do \ test x"$$i" = x"" && continue; \ | | | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | ${MAKE} -s copy-headers-into-framework || exit $$?; \ cd .. || exit 1; \ done if test x"${includesubdir}" = x"${COPY_HEADERS_IF_SUBDIR}"; then \ for i in "" ${INCLUDES}; do \ test x"$$i" = x"" && continue; \ ${MKDIR_P} $$(dirname ${COPY_HEADERS_DESTINATION}/$$i) || exit $$?; \ ${INSTALL} -m 644 $$i ${COPY_HEADERS_DESTINATION}/$$i || exit $$?; \ done \ fi ${AMIGA_LIB} ${AMIGA_LIB_NOINST}: ${EXT_DEPS} ${AMIGA_LIB_OBJS_START} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} ${LINK_STATUS} if ${LD} -o $@ ${AMIGA_LIB_OBJS_START} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA} ${AMIGA_LIB_LDFLAGS} ${AMIGA_LIB_LIBS}; then \ |
︙ | ︙ | |||
244 245 246 247 248 249 250 | fi; \ else \ out="$@"; \ objs=""; \ ars=""; \ for i in ${OBJS} ${OBJS_EXTRA}; do \ case $$i in \ | | | | | | | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | fi; \ else \ out="$@"; \ objs=""; \ ars=""; \ for i in ${OBJS} ${OBJS_EXTRA}; do \ case $$i in \ *.a) \ ars="$$ars $$i" \ ;; \ *.o) \ objs="$$objs $$i" \ ;; \ esac \ done; \ for i in $$ars; do \ dir=".$$(echo $$i | sed 's/\//_/g').objs"; \ rm -fr $$dir; \ mkdir -p $$dir; \ cd $$dir; \ |
︙ | ︙ | |||
291 292 293 294 295 296 297 | fi; \ else \ out="$@"; \ objs=""; \ ars=""; \ for i in ${LIB_OBJS} ${LIB_OBJS_EXTRA}; do \ case $$i in \ | | | | | | | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | fi; \ else \ out="$@"; \ objs=""; \ ars=""; \ for i in ${LIB_OBJS} ${LIB_OBJS_EXTRA}; do \ case $$i in \ *.a) \ ars="$$ars $$i" \ ;; \ *.o) \ objs="$$objs $$i" \ ;; \ esac \ done; \ for i in $$ars; do \ dir=".$$(echo $$i | sed 's/\//_/g').objs"; \ rm -fr $$dir; \ mkdir -p $$dir; \ cd $$dir; \ |
︙ | ︙ | |||
330 331 332 333 334 335 336 | ${LINK_STATUS} rm -f $@ out="$@"; \ objs=""; \ ars=""; \ for i in ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA}; do \ case $$i in \ | | | | | | | | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | ${LINK_STATUS} rm -f $@ out="$@"; \ objs=""; \ ars=""; \ for i in ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_EXTRA}; do \ case $$i in \ *.a) \ ars="$$ars $$i" \ ;; \ *.o) \ objs="$$objs $$i" \ ;; \ esac \ done; \ for i in $$ars; do \ dir=".$$(echo $$i | sed 's/\//_/g').objs"; \ rm -fr $$dir; \ mkdir -p $$dir; \ cd $$dir; \ |
︙ | ︙ | |||
726 727 728 729 730 731 732 | fi \ done if test x"${INSTALL_INCLUDES}" = x"yes"; then \ for i in "" ${INCLUDES}; do \ test x"$$i" = x"" && continue; \ ${INSTALL_STATUS}; \ | | | 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 | fi \ done if test x"${INSTALL_INCLUDES}" = x"yes"; then \ for i in "" ${INCLUDES}; do \ test x"$$i" = x"" && continue; \ ${INSTALL_STATUS}; \ if ${MKDIR_P} $$(dirname ${DESTDIR}${includedir}/${includesubdir}/$$i) && ${INSTALL} -m 644 $$i ${DESTDIR}${includedir}/${includesubdir}/$$i; then \ ${INSTALL_OK}; \ else \ ${INSTALL_FAILED}; \ fi \ done \ fi |
︙ | ︙ | |||
881 882 883 884 885 886 887 | ${DIR_ENTER}; \ ${MAKE} -s clean || exit $$?; \ ${DIR_LEAVE}; \ done : >.deps | | | 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 | ${DIR_ENTER}; \ ${MAKE} -s clean || exit $$?; \ ${DIR_LEAVE}; \ done : >.deps for i in "" ${DEPS} ${OBJS} ${OBJS_EXTRA} ${LIB_OBJS} ${LIB_OBJS_EXTRA} ${AMIGA_LIB_OBJS} ${AMIGA_LIB_OBJS_START} ${AMIGA_LIB_OBJS_EXTRA} ${PLUGIN_OBJS} ${PROG} ${PROG_NOINST} ${SHARED_LIB} ${SHARED_LIB_NOINST} ${AMIGA_LIB} ${AMIGA_LIB_NOINST} ${STATIC_LIB} ${STATIC_LIB_NOINST} ${STATIC_PIC_LIB} ${STATIC_PIC_LIB_NOINST} ${STATIC_AMIGA_LIB} ${STATIC_AMIGA_LIB_NOINST} ${FRAMEWORK} ${PLUGIN} ${PLUGIN_NOINST} ${CLEAN_LIB} ${MO_FILES} ${CLEAN}; do \ test x"$$i" = x"" && continue; \ if test -f $$i -o -d $$i; then \ if rm -fr $$i; then \ ${DELETE_OK}; \ else \ ${DELETE_FAILED}; \ fi \ |
︙ | ︙ |
Modified configure.ac from [9214c38119] to [5a6b4fb150].
|
| | < < < | | < < | | | | | | | | | | | | < < | | | | > | | > | | | | < < | | | | > | < | | | | | | | > | | | < | < < | | | > > | > | < | | | | | | < | | | < < < < | | | | | | | | | | | | | < | | | < < | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | AC_INIT(ObjFW, 1.1dev, js@nil.im) AC_CONFIG_SRCDIR(src) AC_CONFIG_AUX_DIR(build-aux) AC_CONFIG_MACRO_DIR(build-aux/m4) AC_DEFINE(OBJFW_VERSION_MAJOR, 1, [The major version of ObjFW]) AC_DEFINE(OBJFW_VERSION_MINOR, 1, [The minor version of ObjFW]) dnl This may only be set to 1.1 once 1.1 is released AC_SUBST(BUNDLE_VERSION, 1.0.0) AC_SUBST(BUNDLE_SHORT_VERSION, 1.0) for i in configure.ac build-aux/m4/*; do AS_IF([test $i -nt configure], [ AC_MSG_ERROR([$i is newer than configure! Run ./autogen.sh!]) ]) done BUILDSYS_INIT AC_CANONICAL_HOST dnl Used to disable checking for -pedantic on some platforms where it's broken check_pedantic="yes" case "$host" in arm-*-riscos*) AS_IF([test x"$OBJCFLAGS" = x""], [OBJCFLAGS="-O2 -g"]) flags="-mfloat-abi=softfp -mfpu=vfp -mlibscl" ASFLAGS="$ASFLAGS -mfloat-abi=softfp -mfpu=vfp" OBJCFLAGS="$OBJCFLAGS $flags" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags" LDFLAGS="$LDFLAGS $flags" enable_shared="no" enable_threads="no" enable_sockets="no" enable_files="no" ;; m68k-*-amigaos*) AS_IF([test x"$OBJCFLAGS" = x""], [OBJCFLAGS="-O0"]) OBJCFLAGS="$OBJCFLAGS -noixemul" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -noixemul" CPPFLAGS="$CPPFLAGS -D__NO_NET_API" LDFLAGS="$LDFLAGS -noixemul" 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(OBJFWRT_AMIGA_LIB, ['objfwrt${OBJFWRT_LIB_MAJOR}.library']) dnl For 68000, GCC emits calls to helper functions that dnl do not work properly in a library. t="-mcpu=68020 -fbaserel -noixemul -ffreestanding" AC_SUBST(AMIGA_LIB_CFLAGS, $t) t="$t -resident -nostartfiles -nodefaultlibs -ldebug -lc" AC_SUBST(AMIGA_LIB_LDFLAGS, $t) ]) AC_SUBST(LIBBASES_M, libbases.m) ;; 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"]) OBJCFLAGS="$OBJCFLAGS -noixemul" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -noixemul" LDFLAGS="$LDFLAGS -noixemul" LIBS="$LIBS -ldebug" enable_files="yes" # Required for reading ENV: enable_shared="no" supports_amiga_lib="yes" AS_IF([test x"$enable_amiga_lib" != x"no"], [ AC_SUBST(OBJFWRT_AMIGA_LIB, ['objfwrt${OBJFW_LIB_MAJOR}ppc.library']) t="-mresident32 -ffreestanding -noixemul" AC_SUBST(AMIGA_LIB_CFLAGS, $t) t="-mresident32 -nostartfiles -nodefaultlibs -noixemul -ldebug" AC_SUBST(AMIGA_LIB_LDFLAGS, "$t -lc") ]) AC_SUBST(LIBBASES_M, libbases.m) ;; *-msdosdjgpp*) enable_shared="no" enable_threads="no" enable_sockets="no" ;; *-*-mingw*) LDFLAGS="$LDFLAGS -Wl,--allow-multiple-definition" LIBS="$LIBS -lversion" AC_SUBST(USE_SRCS_WINDOWS, '${SRCS_WINDOWS}') ;; *-psp-*) AS_IF([test x"$DEVKITPSP" = x""], [ AC_MSG_ERROR([DEVKITPSP is not set! Please set DEVKITPSP.]) ]) AS_IF([test x"$OBJCFLAGS" = x""], [OBJCFLAGS="-O2"]) OBJCFLAGS="$OBJCFLAGS -G0" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -G0" CPPFLAGS="$CPPFLAGS -I$DEVKITPSP/psp/sdk/include" LDFLAGS="$LDFLAGS -G0" LIBS="$LIBS -L$DEVKITPSP/psp/sdk/lib -lpspdebug -lpspdisplay" LIBS="$LIBS -lpspge -lpspctrl -lpspsdk -lc -lpspnet" LIBS="$LIBS -lpspnet_inet -lpspnet_apctl -lpspnet_resolver" LIBS="$LIBS -lpsputility -lpspuser -lpspkernel -lgcc -lpsplibc" enable_shared="no" enable_threads="no" # TODO enable_sockets="no" # TODO check_pedantic="no" AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map']) ;; hppa*-*-hpux*) dnl Don't default to -g: It creates errors from the assembler and breaks dnl exceptions. AS_IF([test x"$OBJCFLAGS" = x""], [OBJCFLAGS="-O2"]) dnl HP-UX 11.11's inttypes.h defines UINTPTR_MAX etc. to nothing. GCC's dnl stdint.h defines those correctly, but if inttypes.h gets included dnl after something included stdint.h, it gets broken again. Therefore, dnl always include inttypes.h as the very first thing. dnl We need to put this into OBJCFLAGS and not CPPFLAGS as CPPFLAGS are 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} : ${GREP:=grep.exe} : ${RANLIB:=ranlib.exe} ]) AC_LANG([Objective C]) case "$host_os" in morphos*) dnl Don't use clang on MorphOS - it does not support baserel, which is dnl required for the .library. potential_compilers="gcc" ;; *) potential_compilers="clang egcc gcc" ;; esac AC_PROG_OBJC($potential_compilers) AC_PROG_OBJCPP AC_PROG_LN_S AC_PROG_EGREP BUILDSYS_CHECK_IOS AC_ARG_WITH(wii, AS_HELP_STRING([--with-wii], [build for Wii])) AS_IF([test x"$with_wii" = x"yes"], [ |
︙ | ︙ | |||
171 172 173 174 175 176 177 178 179 180 181 182 183 184 | 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 AC_DEFINE(OF_WII, 1, [Whether we are compiling for Wii]) AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map']) ]) AC_ARG_WITH(wii-u, AS_HELP_STRING([--with-wii-u], [build for Wii U])) | > | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | 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]) AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map']) ]) AC_ARG_WITH(wii-u, AS_HELP_STRING([--with-wii-u], [build for Wii U])) |
︙ | ︙ | |||
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | 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 check_pedantic="no" AC_DEFINE(OF_NINTENDO_3DS, 1, [Whether we are compiling for Nintendo 3DS]) AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map']) ]) CPP="$OBJCPP" CPPFLAGS="$CPPFLAGS $OBJCPPFLAGS -DOF_COMPILING_OBJFW" flags="-fexceptions -fobjc-exceptions -funwind-tables" flags="$flags -fconstant-string-class=OFConstantString" OBJCFLAGS="$OBJCFLAGS -Wall $flags" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags" dnl amiga-gcc requires -fexceptions in LDFLAGS in order to link in the glue code dnl for registering the frames. LDFLAGS="$LDFLAGS -fexceptions" case "$OBJC" in | > | | > | | | | | < < | | | > | | < | < | < < < < < < < | | < | | | | | | < < < < < | < < | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | 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]) AC_SUBST(MAP_LDFLAGS, ['-Wl,-Map,$@.map']) ]) CPP="$OBJCPP" CPPFLAGS="$CPPFLAGS $OBJCPPFLAGS -DOF_COMPILING_OBJFW" flags="-fexceptions -fobjc-exceptions -funwind-tables" flags="$flags -fconstant-string-class=OFConstantString" OBJCFLAGS="$OBJCFLAGS -Wall $flags" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flags" dnl amiga-gcc requires -fexceptions in LDFLAGS in order to link in the glue code dnl for registering the frames. LDFLAGS="$LDFLAGS -fexceptions" case "$OBJC" in *clang*) case "$host" in mips*-*-*) dnl Clang generates MIPS assembly not accepted by GNU as, dnl however, Clang's integrated assembler doesn't accept dnl everything used in ObjFW's assembly files. Therefore, use dnl the integrated assembler for ObjC files, but not for dnl assembly files. OBJCFLAGS="$OBJCFLAGS -integrated-as" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -integrated-as" ;; i?86-*-darwin* | x86_64-*-darwin*) dnl Don't use -no-integrated-as on Darwin. It breaks building dnl for the iOS simulator. ;; sparc64-*-*openbsd*) dnl Clang generates assembly output on SPARC64 that OpenBSD's dnl assembler does not accept. flag="-integrated-as" OBJCFLAGS="$OBJCFLAGS $flag" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flag" ;; esac ;; esac AX_CHECK_COMPILER_FLAGS(-std=gnu11, [ OBJCFLAGS="$OBJCFLAGS -std=gnu11" ], [ AX_CHECK_COMPILER_FLAGS(-std=gnu1x, [ OBJCFLAGS="$OBJCFLAGS -std=gnu1x" ], [ AX_CHECK_COMPILER_FLAGS(-std=gnu99, [OBJCFLAGS="$OBJCFLAGS -std=gnu99"]) ]) ]) AX_CHECK_COMPILER_FLAGS(-pipe, [OBJCFLAGS="$OBJCFLAGS -pipe"]) AX_CHECK_COMPILER_FLAGS(-fno-common, [OBJCFLAGS="$OBJCFLAGS -fno-common"]) AX_CHECK_COMPILER_FLAGS(-Xclang -fno-constant-cfstrings, [ flag="-Xclang -fno-constant-cfstrings" OBJCFLAGS="$OBJCFLAGS $flag" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flag" ]) AX_CHECK_COMPILER_FLAGS([-Wsign-compare -Werror], |
︙ | ︙ | |||
339 340 341 342 343 344 345 | [OBJCFLAGS="$OBJCFLAGS -Wsemicolon-before-method-body"]) AX_CHECK_COMPILER_FLAGS([-Wobjc-missing-property-synthesis -Werror], [OBJCFLAGS="$OBJCFLAGS -Wobjc-missing-property-synthesis"]) AX_CHECK_COMPILER_FLAGS([-Wmissing-method-return-type -Werror], [OBJCFLAGS="$OBJCFLAGS -Wmissing-method-return-type"]) case "$host" in | | | < | | | > | | | | | | | | | | | | | | | > < < < < < | 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | [OBJCFLAGS="$OBJCFLAGS -Wsemicolon-before-method-body"]) AX_CHECK_COMPILER_FLAGS([-Wobjc-missing-property-synthesis -Werror], [OBJCFLAGS="$OBJCFLAGS -Wobjc-missing-property-synthesis"]) AX_CHECK_COMPILER_FLAGS([-Wmissing-method-return-type -Werror], [OBJCFLAGS="$OBJCFLAGS -Wmissing-method-return-type"]) case "$host" in m68k-*-amigaos*) dnl The inline headers generate code that triggers -Wpointer-sign. OBJCFLAGS="$OBJCFLAGS -Wno-pointer-sign" ;; esac AC_MSG_CHECKING(whether Objective C compiler supports properties) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ #ifdef __has_attribute # if __has_attribute(objc_root_class) __attribute__((__objc_root_class__)) # endif #endif @interface Foo { id bar; } @property (nonatomic, retain) id bar; @end ], [[ Foo *foo = (id)0; [foo setBar: (id)0]; foo = [foo bar]; ]]) ], [ AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) AC_MSG_ERROR(Compiler does not support properties!) ]) AC_CHECK_TOOL(AR, ar) AC_PROG_RANLIB AC_ARG_ENABLE(shared, AS_HELP_STRING([--disable-shared], [do not build shared library])) AS_IF([test x"$enable_shared" != x"no"], [ BUILDSYS_SHARED_LIB AC_SUBST(OBJFW_SHARED_LIB, "${LIB_PREFIX}objfw${LIB_SUFFIX}") AC_SUBST(EXCEPTIONS_LIB_A, "exceptions.lib.a") AC_SUBST(FORWARDING_LIB_A, "forwarding.lib.a") AC_SUBST(LOOKUP_ASM_LIB_A, "lookup-asm.lib.a") BUILDSYS_FRAMEWORK([ AC_SUBST(OBJFW_FRAMEWORK, "ObjFW.framework") build_framework="yes" ]) ], [ AC_DEFINE(OF_NO_SHARED, 1, [Whether no shared library was built]) |
︙ | ︙ | |||
410 411 412 413 414 415 416 | TESTS_LIBS="-L../src/runtime -L../src/runtime/linklib $TESTS_LIBS" TESTS_LIBS="-L../src -lobjfw $TESTS_LIBS" ]) AC_ARG_ENABLE(amiga-lib, AS_HELP_STRING([--disable-amiga-lib], [do not build Amiga library])) AS_IF([test x"$supports_amiga_lib" != x"yes"], [enable_amiga_lib="no"]) | | | | > > > > > | < < < < < | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | TESTS_LIBS="-L../src/runtime -L../src/runtime/linklib $TESTS_LIBS" TESTS_LIBS="-L../src -lobjfw $TESTS_LIBS" ]) AC_ARG_ENABLE(amiga-lib, AS_HELP_STRING([--disable-amiga-lib], [do not build Amiga library])) AS_IF([test x"$supports_amiga_lib" != x"yes"], [enable_amiga_lib="no"]) AS_IF([test x"$enable_amiga_lib" != x"no"], [ AC_SUBST(OBJFW_STATIC_LIB, "libobjfw.a") AC_SUBST(EXCEPTIONS_A, "exceptions.a") AC_SUBST(FORWARDING_A, "forwarding.a") AC_SUBST(LOOKUP_ASM_AMIGALIB_A, "lookup-asm.amigalib.a") ]) AC_ARG_ENABLE(static, AS_HELP_STRING([--enable-static], [build static library])) AS_IF([test x"$enable_shared" = x"no" -a x"$enable_amiga_lib" = x"no"], [ enable_static="yes" ]) AS_IF([test x"$enable_static" = x"yes"], [ AC_SUBST(OBJFW_STATIC_LIB, "libobjfw.a") AC_SUBST(EXCEPTIONS_A, "exceptions.a") AC_SUBST(FORWARDING_A, "forwarding.a") AC_SUBST(LOOKUP_ASM_A, "lookup-asm.a") ]) AC_DEFINE_UNQUOTED(PLUGIN_SUFFIX, "$PLUGIN_SUFFIX", [Suffix for plugins]) AS_IF([test x"$enable_files" != x"no" -a x"$PLUGIN_SUFFIX" != x""], [ AC_SUBST(USE_SRCS_PLUGINS, '${SRCS_PLUGINS}') AC_SUBST(TESTPLUGIN, "plugin") AC_DEFINE(OF_HAVE_PLUGINS, 1, [Whether we have plugin support]) |
︙ | ︙ | |||
451 452 453 454 455 456 457 | ]) AC_MSG_CHECKING(whether we need -D_GNU_SOURCE) AC_EGREP_CPP(egrep_cpp_yes, [ #include <stdlib.h> #if defined(__GLIBC__) || defined(__MINGW32__) || \ | | | | | | 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | ]) AC_MSG_CHECKING(whether we need -D_GNU_SOURCE) AC_EGREP_CPP(egrep_cpp_yes, [ #include <stdlib.h> #if defined(__GLIBC__) || defined(__MINGW32__) || \ defined(__NEWLIB__) || defined(__MORPHOS__) || defined(__MINT__) egrep_cpp_yes #endif ], [ AC_MSG_RESULT(yes) CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS" gnu_source="yes" ], [ AC_MSG_RESULT(no) ]) case "$host_os" in solaris*) CPPFLAGS="-D__EXTENSIONS__ -D_POSIX_PTHREAD_SEMANTICS $CPPFLAGS" ;; esac objc_runtime="ObjFW runtime" AC_CHECK_HEADER(objc/objc.h) AC_MSG_CHECKING(which Objective C runtime to use) AC_ARG_ENABLE(runtime, AS_HELP_STRING([--enable-runtime], [use the included runtime])) |
︙ | ︙ | |||
495 496 497 498 499 500 501 | : ]) ]) ]) AC_MSG_RESULT($objc_runtime) case "$objc_runtime" in | | | < | | | | > | 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 | : ]) ]) ]) AC_MSG_RESULT($objc_runtime) case "$objc_runtime" in "ObjFW runtime") AC_DEFINE(OF_OBJFW_RUNTIME, 1, [Whether we use the ObjFW runtime]) AC_MSG_CHECKING([whether -fobjc-runtime=objfw is supported]) old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -Xclang -fobjc-runtime=objfw" AC_LINK_IFELSE([ AC_LANG_PROGRAM([ #ifdef __has_attribute # if __has_attribute(objc_root_class) __attribute__((__objc_root_class__)) # endif #endif @interface Test + (void)test; |
︙ | ︙ | |||
529 530 531 532 533 534 535 | return (void *)0; } void __objc_exec_class(void *module) { } | | > | < | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | < | | | > > | | | | | | | | | | | | | < < | | | | > | | | | | | | | | > | | | | | | | | | | | | | | < < | | | | | | | < | | | | | | > > > | | | | | | > > | > > > > > > > > | > > | | | | | < | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > | > | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 | return (void *)0; } void __objc_exec_class(void *module) { } ], [[ [Test test]; ]]) ], [ OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -Xclang -fobjc-runtime=objfw" AC_MSG_RESULT(yes) ], [ OBJCFLAGS="$old_OBJCFLAGS -fgnu-runtime" OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -fgnu-runtime" AC_MSG_RESULT(no) old_compiler="yes" ]) AC_SUBST(RUNTIME, "runtime") AC_CONFIG_FILES(src/runtime/Info.plist) AS_IF([test x"$enable_shared" != x"no"], [ AC_SUBST(OBJFWRT_SHARED_LIB, "${LIB_PREFIX}objfwrt${LIB_SUFFIX}") ]) AS_IF([test x"$enable_static" = x"yes"], [ AC_SUBST(OBJFWRT_STATIC_LIB, "libobjfwrt.a") ]) AS_IF([test x"$build_framework" = x"yes"], [ AC_SUBST(OBJFWRT_FRAMEWORK, "ObjFWRT.framework") AC_SUBST(RUNTIME_FRAMEWORK_LIBS, "-framework ObjFWRT") ]) AS_IF([test x"$enable_amiga_lib" != x"no"], [ AC_SUBST(RUNTIME_LIBS, "-lobjfwrt.library") AC_SUBST(LINKLIB, linklib) tmp="../src/runtime/linklib/libobjfwrt.library.a" AC_SUBST(LIBOBJFWRT_DEP, "$tmp") AC_SUBST(LIBOBJFWRT_DEP_LVL2, "../$tmp") ], [ AC_SUBST(RUNTIME_LIBS, "-lobjfwrt") ]) AS_IF([test x"$enable_shared" = x"no" \ -a x"$enable_amiga_lib" = x"no"], [ AC_SUBST(LIBOBJFWRT_DEP, "../src/runtime/libobjfwrt.a") AC_SUBST(LIBOBJFWRT_DEP_LVL2, "../../src/runtime/libobjfwrt.a") ]) AS_IF([test x"$enable_seluid24" = x"yes"], [ AC_DEFINE(OF_SELUID24, 1, [Whether to use 24 bit selector UIDs]) ]) AC_MSG_CHECKING(for exception type) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ extern void foo(); ], [ @try { foo(); } @finally { foo(); } ]) ], [ AS_IF([$EGREP __gnu_objc_personality_v0 conftest.$ac_objext \ >/dev/null], [ exception_type="DWARF" ]) AS_IF([$EGREP __gnu_objc_personality_sj0 conftest.$ac_objext \ >/dev/null], [ exception_type="SjLj" ]) AS_IF([$EGREP __gnu_objc_personality_seh0 conftest.$ac_objext \ >/dev/null], [ exception_type="SEH" ]) case "$exception_type" in DWARF) AC_DEFINE(HAVE_DWARF_EXCEPTIONS, 1, [Whether DWARF exceptions are used]) raise_exception="_Unwind_RaiseException" ;; SjLj) AC_DEFINE(HAVE_SJLJ_EXCEPTIONS, 1, [Whether SjLj exceptions are used]) raise_exception="_Unwind_SjLj_RaiseException" ;; SEH) AC_DEFINE(HAVE_SEH_EXCEPTIONS, 1, [Whether SEH exceptions are used]) raise_exception="_Unwind_RaiseException" ;; *) AC_MSG_RESULT(unknown) AC_MSG_ERROR([Exception type not detected!]) ;; esac AC_MSG_RESULT($exception_type) ], [ AC_MSG_RESULT(exceptions unavailable!) AC_MSG_ERROR([Exceptions not accepted by compiler!]) ]) AC_SEARCH_LIBS($raise_exception, [c++abi gcc_s gcc unwind], [ dnl c++abi requires pthread on OpenBSD AS_IF([test x"$ac_lib" = x"c++abi"], [LIBS="$LIBS -lpthread"]) ], [ AC_MSG_ERROR([$raise_exception missing!]) ], [-lpthread]) AC_CHECK_FUNCS(_Unwind_GetDataRelBase _Unwind_GetTextRelBase) ;; "Apple runtime") AC_DEFINE(OF_APPLE_RUNTIME, 1, [Whether we use the Apple ObjC runtime]) AC_CHECK_LIB(objc, objc_msgSend, [ AC_SUBST(RUNTIME_LIBS, "-lobjc") AC_SUBST(RUNTIME_FRAMEWORK_LIBS, "-lobjc") ], [ AC_MSG_ERROR([libobjc not found!]) ]) old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -lobjc" AC_CHECK_FUNC(objc_autoreleasePoolPush, [], [ AC_SUBST(RUNTIME_AUTORELEASE_M, "runtime/autorelease.m") ]) AC_CHECK_FUNC(objc_constructInstance, [], [ AC_SUBST(RUNTIME_INSTANCE_M, "runtime/instance.m") ]) OBJCFLAGS="$old_OBJCFLAGS" ;; esac 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) ;; esac case "$host_os" in darwin*) AC_SUBST(LDFLAGS_REEXPORT, ["-Wl,-reexport-lobjfw"]) AS_IF([test x"$objc_runtime" = x"Apple runtime"], [ AC_SUBST(REEXPORT_RUNTIME, ["-Wl,-reexport-lobjc"]) AC_SUBST(REEXPORT_RUNTIME_FRAMEWORK, ["-Wl,-reexport-lobjc"]) LDFLAGS="$LDFLAGS -Wl,-U,_NSFoundationVersionNumber" ]) AS_IF([test x"$objc_runtime" = x"ObjFW runtime"], [ AS_IF([test x"$exception_type" = x"DWARF"], [ LDFLAGS="$LDFLAGS -Wl,-U,___gxx_personality_v0" ]) AS_IF([test x"$exception_type" = x"SjLj"], [ LDFLAGS="$LDFLAGS -Wl,-U,___gxx_personality_sj0" ]) AC_SUBST(REEXPORT_RUNTIME, ["-Wl,-reexport-lobjfwrt"]) AC_SUBST(REEXPORT_RUNTIME_FRAMEWORK, ["-Wl,-reexport_framework,ObjFWRT"]) ]) AC_CHECK_HEADERS(sysdir.h) AC_CHECK_FUNCS(sysdir_start_search_path_enumeration) AS_IF([test x"$host_is_ios" = x"yes"], [ AC_SUBST(TESTS_STATIC_LIB, tests.a) TESTS_LIBS="$TESTS_LIBS -framework CoreFoundation" ]) ;; esac AC_MSG_CHECKING(whether Objective C compiler supports ARC) old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -fobjc-arc -fobjc-arc-exceptions" AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ #ifdef __has_attribute # if __has_attribute(objc_root_class) __attribute__((__objc_root_class__)) # endif #endif @interface Foo { struct objc_class *_isa; } + (id)alloc; @end @implementation Foo + (id)alloc { return (id)0; } @end ], [[ __weak id foo = [Foo alloc]; (void)foo; ]]) ], [ AC_MSG_RESULT(yes) AC_DEFINE(COMPILER_SUPPORTS_ARC, 1, [Whether the compiler supports ARC]) AC_SUBST(RUNTIME_ARC_TESTS_M, RuntimeARCTests.m) ], [ AC_MSG_RESULT(no) ]) OBJCFLAGS="$old_OBJCFLAGS" AC_C_BIGENDIAN([ AC_DEFINE(OF_BIG_ENDIAN, 1, [Whether we are big endian]) ]) AS_IF([test x"$ac_cv_c_bigendian" = x"universal"], [ AC_DEFINE(OF_UNIVERSAL, 1, [Whether we are building a universal binary]) ]) AC_MSG_CHECKING(for SSIZE_MAX) AC_EGREP_CPP(egrep_cpp_yes, [ #include <stdint.h> #include <limits.h> #ifdef SSIZE_MAX egrep_cpp_yes #endif ], [ AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) AC_DEFINE(SSIZE_MAX, [(SIZE_MAX / 2)], [Maximum value for ssize_t]) ]) AC_MSG_CHECKING(for UINTPTR_MAX) AC_EGREP_CPP(egrep_cpp_yes, [ #include <stdint.h> #include <limits.h> #ifdef UINTPTR_MAX egrep_cpp_yes #endif ], [ AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) AC_CHECK_SIZEOF(uintptr_t) AC_DEFINE(UINTPTR_MAX, [(SIZEOF_UINTPTR_T * CHAR_BIT)], [Maximum value for uintptr_t]) ]) AC_CHECK_HEADER(inttypes.h, [AC_DEFINE(OF_HAVE_INTTYPES_H, 1, [Whether we have inttypes.h])]) AC_CHECK_HEADER(sys/types.h, [AC_DEFINE(OF_HAVE_SYS_TYPES_H, 1, [Whether we have sys/types.h])]) |
︙ | ︙ | |||
823 824 825 826 827 828 829 | AS_IF([test x"$ac_cv_sizeof_float" != x"4" -o x"$ac_cv_sizeof_double" != x"8"], [AC_MSG_ERROR( [Floating point implementation does not conform to IEEE 754!])]) AC_MSG_CHECKING(for floating point endianess) fp_endianess="unknown" AS_IF([test x"$ac_cv_c_bigendian" != x"universal"], [ | | > | | < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | > > | | | | | | | > > > > > > | | < | | | | | | | | | < < | | | | | | | | | < | > > | < | | < | | | < < | | | | | | | | | | | 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | AS_IF([test x"$ac_cv_sizeof_float" != x"4" -o x"$ac_cv_sizeof_double" != x"8"], [AC_MSG_ERROR( [Floating point implementation does not conform to IEEE 754!])]) AC_MSG_CHECKING(for floating point endianess) fp_endianess="unknown" AS_IF([test x"$ac_cv_c_bigendian" != x"universal"], [ AC_COMPILE_IFELSE([ AC_LANG_SOURCE([ double endianess = 2.993700760838795055656993580068609688772747263874402942272934826871811872228512759832626847251963763755836687759498519784550143745834860002945223766052808125982053455555265216112722718870586961456110693379343178124592311441022662940307099598578775368547768968914916965731708568179631324904813506101190853720749196062963892799499230635163056742330563321122389331703618066046034494287335316842529021563862331183541255013987734473643350285400060357711238514186776429325214739886098119655678483017894951556639821088508565036657794343031121375178126860889964700274558728491825977274341798997758923017217660272136611938897932105874133412726223468780517578125e-259; ]) ], [ AS_IF([$EGREP BigEnd conftest.$ac_objext >/dev/null], [ AC_DEFINE(OF_FLOAT_BIG_ENDIAN, 1, [Whether floats are big endian]) fp_endianess="big endian" ], [ AS_IF([$EGREP dnEgiB conftest.$ac_objext >/dev/null], [ fp_endianess="little endian" ]) ]) ]) ], [ fp_endianess="universal" ]) AC_MSG_RESULT($fp_endianess) AS_IF([test x"$fp_endianess" = x"unknown"], [ AC_MSG_ERROR( [Floating point implementation does not conform to IEEE 754!])]) case "$host_cpu" in arm* | earm*) AC_MSG_CHECKING(for VFP2 or above) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([], [ #if !defined(__arm64__) && !defined(__aarch64__) && \ !defined(__ARM64_ARCH_8__) __asm__ __volatile__ ( "vstmdb sp!, {d0-d7}" ); #endif ]) ], [ AC_DEFINE(HAVE_VFP2, 1, [Whether we have VFP2 or above]) AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) ]) ;; esac AC_CHECK_LIB(m, fmod, LIBS="$LIBS -lm") AC_CHECK_LIB(complex, creal, TESTS_LIBS="$TESTS_LIBS -lcomplex") AC_CHECK_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-*) dnl asprintf is broken on the PSP have_asprintf="no" ;; *) have_asprintf="yes" AC_DEFINE(HAVE_ASPRINTF, 1, [Whether we have asprintf()]) ;; esac ], [ have_asprintf="no" ]) AC_ARG_ENABLE(unicode-tables, AS_HELP_STRING([--disable-unicode-tables], [Disable Unicode tables])) AS_IF([test x"$enable_unicode_tables" != x"no"], [ AC_DEFINE(OF_HAVE_UNICODE_TABLES, 1, [Whether to build with Unicode tables]) AC_SUBST(UNICODE_M, "unicode.m") ]) ENCODINGS_SRCS="" AC_DEFUN([ENCODING_FLAG], [ AC_ARG_ENABLE($1, AS_HELP_STRING([--disable-$1], [Disables support for $3])) AS_IF([test x"$enable_$2" != x"no"], [ AC_DEFINE($4, 1, [Whether we have support for $3]) ENCODINGS_SRCS="$ENCODINGS_SRCS $1.m" ]) ]) ENCODING_FLAG(codepage-437, codepage_437, [Codepage 437], HAVE_CODEPAGE_437) ENCODING_FLAG(codepage-850, codepage_850, [Codepage 850], HAVE_CODEPAGE_850) ENCODING_FLAG(codepage-858, codepage_858, [Codepage 858], HAVE_CODEPAGE_858) ENCODING_FLAG(iso-8859-2, iso_8859_2, [ISO 8859-2], HAVE_ISO_8859_2) ENCODING_FLAG(iso-8859-3, iso_8859_3, [ISO 8859-3], HAVE_ISO_8859_3) ENCODING_FLAG(iso-8859-15, iso_8859_15, [ISO 8859-15], HAVE_ISO_8859_15) ENCODING_FLAG(koi8-r, koi8_r, [KOI8-R], HAVE_KOI8_R) ENCODING_FLAG(koi8-u, koi8_u, [KOI8-U], HAVE_KOI8_U) ENCODING_FLAG(mac-roman, mac_roman, [Mac Roman encoding], HAVE_MAC_ROMAN) ENCODING_FLAG(windows-1251, windows_1251, [Windows-1251], HAVE_WINDOWS_1251) ENCODING_FLAG(windows-1252, windows_1252, [Windows-1252], HAVE_WINDOWS_1252) AS_IF([test x"$ENCODINGS_SRCS" = x""], [ ENCODINGS_SRCS="dummy.m" ]) AC_SUBST(ENCODINGS_SRCS) AS_IF([test x"$enable_shared" != x"no"], [ AC_SUBST(ENCODINGS_LIB_A, "encodings.lib.a") ]) AS_IF([test x"$enable_static" = x"yes" -o x"$enable_shared" = x"no"], [ AC_SUBST(ENCODINGS_A, "encodings.a") ]) AC_CHECK_FUNCS(arc4random arc4random_buf getrandom random, break) AS_IF([test x"$host_os" != x"morphos"], [ AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl") ]) AC_CHECK_HEADERS_ONCE(dlfcn.h) case "$host_os" in netbsd*) dnl dladdr exists on NetBSD, but it is completely broken. dnl When using it with code that uses __thread, it freezes the process dnl so that it has to be killed using SIGKILL. dnl When disabling __thread, it doesn't freeze, but all symbols are dnl wrong. ;; *) AC_CHECK_FUNCS(dladdr) ;; esac AC_CHECK_HEADERS(sys/mman.h) AC_CHECK_FUNCS(mmap mlock) AC_ARG_ENABLE(threads, AS_HELP_STRING([--disable-threads], [disable thread support])) |
︙ | ︙ | |||
1005 1006 1007 1008 1009 1010 1011 | dnl Use -Wp, as we only use it for the preprocessor. AX_CHECK_COMPILER_FLAGS([-Wp,-pthread], [ CPPFLAGS="$CPPFLAGS -Wp,-pthread" ], [ CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_THREAD_SAFE" ]) | | | > | | | > | > | | | | | > | 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 | dnl Use -Wp, as we only use it for the preprocessor. AX_CHECK_COMPILER_FLAGS([-Wp,-pthread], [ CPPFLAGS="$CPPFLAGS -Wp,-pthread" ], [ CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_THREAD_SAFE" ]) AC_CHECK_LIB(pthread, main, LIBS="$LIBS -lpthread") AC_LINK_IFELSE([ AC_LANG_PROGRAM([ #include <pthread.h> ], [ pthread_create(NULL, NULL, NULL, NULL); ]) ], [], [ AC_MSG_ERROR(No supported threads found!) ]) AC_DEFINE(OF_HAVE_PTHREADS, 1, [Whether we have pthreads]) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ #include <pthread.h> ], [ pthread_mutexattr_t attr; pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); ]) ], [ AC_DEFINE(OF_HAVE_RECURSIVE_PTHREAD_MUTEXES, 1, [If pthread mutexes can be recursive]) ]) AC_CHECK_FUNC(pthread_spin_lock, [ have_spinlocks="yes" |
︙ | ︙ | |||
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 | AC_CHECK_HEADERS(pthread_np.h, [], [], [#include <pthread.h>]) AC_CHECK_FUNCS(pthread_set_name_np pthread_setname_np, break) ;; esac AC_DEFINE(OF_HAVE_THREADS, 1, [Whether we have threads]) AC_SUBST(USE_SRCS_THREADS, '${SRCS_THREADS}') AC_ARG_ENABLE(compiler-tls, AS_HELP_STRING([--disable-compiler-tls], [disable compiler thread local storage])) case "$host" in | > | | | | | | | | > > > > > | > | | | > | > | | | > | 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 | AC_CHECK_HEADERS(pthread_np.h, [], [], [#include <pthread.h>]) AC_CHECK_FUNCS(pthread_set_name_np pthread_setname_np, break) ;; esac AC_DEFINE(OF_HAVE_THREADS, 1, [Whether we have threads]) AC_SUBST(USE_SRCS_THREADS, '${SRCS_THREADS}') AC_SUBST(OBJC_SYNC, objc_sync) AC_ARG_ENABLE(compiler-tls, AS_HELP_STRING([--disable-compiler-tls], [disable compiler thread local storage])) case "$host" in aarch64*-*-android*) dnl Compiler TLS is broken on AArch64 Android with Clang enable_compiler_tls="no" ;; m68k-*-amigaos* | powerpc-*-amigaos*) dnl Compiler TLS is broken on AmigaOS enable_compiler_tls="no" ;; *-*-morphos*) dnl Compiler TLS needs helpers that we don't want in the dnl .library enable_compiler_tls="no" ;; esac AS_IF([test x"$enable_compiler_tls" != x"no"], [ AC_CHECK_HEADER(threads.h, [ AC_DEFINE(OF_HAVE_THREADS_H, 1, [Whether we have threads.h]) ]) AC_MSG_CHECKING(whether _Thread_local works) AC_LINK_IFELSE([ AC_LANG_PROGRAM([ static _Thread_local int x = 0; ], [ x++; ]) ], [ AS_IF([test x"$enable_shared" != x"no"], [ old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -fPIC" AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ static _Thread_local int x = 0; ], [ x++; ]) ], [ AC_MSG_RESULT(yes) AC_DEFINE(OF_HAVE__THREAD_LOCAL, 1, [Whether _Thread_local works]) have_thread_local="yes" ], [ AC_MSG_RESULT(no) |
︙ | ︙ | |||
1105 1106 1107 1108 1109 1110 1111 | ]) ], [ AC_MSG_RESULT(no) ]) AS_IF([test x"$have_thread_local" != x"yes"], [ AC_MSG_CHECKING(whether __thread works) | | > > | > | | | | | | > | > | | | > | 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 | ]) ], [ AC_MSG_RESULT(no) ]) AS_IF([test x"$have_thread_local" != x"yes"], [ AC_MSG_CHECKING(whether __thread works) AC_LINK_IFELSE([ AC_LANG_PROGRAM([ /* * It seems __thread is buggy with * GCC 4.1 */ #if __GNUC__ == 4 && __GNUC_MINOR__ < 2 # error buggy #endif __thread int x = 0; ], [ x++; ]) ], [ AS_IF([test x"$enable_shared" != x"no"], [ old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -fPIC" AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ __thread int x = 0; ], [ x++; ]) ], [ AC_MSG_RESULT(yes) AC_DEFINE(OF_HAVE___THREAD, 1, [Whether __thread works] ) ], [ AC_MSG_RESULT(no) |
︙ | ︙ | |||
1160 1161 1162 1163 1164 1165 1166 | AC_MSG_RESULT(yes) atomic_ops="assembly implementation" ], [ AC_MSG_RESULT(no) ]) AC_MSG_CHECKING(whether __atomic_* works) | | > | | | | | | | | | > > > | > | | | | > | 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 | AC_MSG_RESULT(yes) atomic_ops="assembly implementation" ], [ AC_MSG_RESULT(no) ]) AC_MSG_CHECKING(whether __atomic_* works) AC_LINK_IFELSE([ AC_LANG_PROGRAM([ #include <stdbool.h> #include <stdint.h> ], [ int32_t i, j; if (__atomic_add_fetch(&i, 1, __ATOMIC_RELAXED)) j = __atomic_sub_fetch(&i, 1, __ATOMIC_RELAXED); while (!__atomic_compare_exchange_n(&i, &j, 1, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED)); __atomic_thread_fence(__ATOMIC_SEQ_CST); ]) ], [ AC_MSG_RESULT(yes) test x"$atomic_ops" = x"none" && \ atomic_ops="__atomic_* builtins" AC_DEFINE(OF_HAVE_ATOMIC_BUILTINS, 1, [Whether __atomic_* builtins are available]) ], [ AC_MSG_RESULT(no) ]) AC_MSG_CHECKING(whether __sync_* works) AC_LINK_IFELSE([ AC_LANG_PROGRAM([ #include <stdint.h> ], [ int32_t i, j; if (__sync_add_and_fetch(&i, 1)) j = __sync_sub_and_fetch(&i, 1); while (!__sync_bool_compare_and_swap(&i, 0, 1)); ]) ], [ AC_MSG_RESULT(yes) test x"$atomic_ops" = x"none" && \ atomic_ops="__sync_* builtins" AC_DEFINE(OF_HAVE_SYNC_BUILTINS, 1, [Whether __sync_* builtins are available]) ], [ |
︙ | ︙ | |||
1222 1223 1224 1225 1226 1227 1228 | AS_IF([test x"$enable_files" != x"no"], [ AC_DEFINE(OF_HAVE_FILES, 1, [Whether we have files]) AC_SUBST(USE_SRCS_FILES, '${SRCS_FILES}') AC_SUBST(OFARC, "ofarc") AC_SUBST(OFHASH, "ofhash") case "$host_os" in | | | | | | | < | | | | 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 | AS_IF([test x"$enable_files" != x"no"], [ AC_DEFINE(OF_HAVE_FILES, 1, [Whether we have files]) AC_SUBST(USE_SRCS_FILES, '${SRCS_FILES}') AC_SUBST(OFARC, "ofarc") AC_SUBST(OFHASH, "ofhash") case "$host_os" in msdosdjgpp*) dnl DJGPP has the type, but it's not really usable. ;; *) AC_CHECK_TYPE(off64_t, [ AC_DEFINE(OF_HAVE_OFF64_T, 1, [Whether we have off64_t]) AC_CHECK_FUNCS([lseek64 lstat64 open64 stat64]) ]) ;; esac AC_CHECK_HEADERS([pwd.h grp.h]) AC_CHECK_FUNC(chmod, [ AC_DEFINE(OF_HAVE_CHMOD, 1, [Whether we have chmod()]) ]) AC_CHECK_FUNC(chown, [ |
︙ | ︙ | |||
1255 1256 1257 1258 1259 1260 1261 | AC_CHECK_MEMBERS([struct stat.st_birthtime], [], [], [ #include <sys/stat.h> ]) old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -Werror" AC_MSG_CHECKING(for readdir_r) | | > | | | | | > | | > > > > > > > > > > > > > | > | | | | | | | | | | | | | | | | > | > | | | | | | > < < < < | | | < < | | | | | | | | | | | < < < < < < > > > | 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 | AC_CHECK_MEMBERS([struct stat.st_birthtime], [], [], [ #include <sys/stat.h> ]) old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -Werror" AC_MSG_CHECKING(for readdir_r) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ #include <dirent.h> ], [ DIR *dir = 0; struct dirent entry, *result; readdir_r(dir, &entry, &result); ]) ], [ AC_MSG_RESULT(yes) AC_DEFINE(HAVE_READDIR_R, 1, [Whether we have readdir_r()]) ], [ AC_MSG_RESULT(no) ]) OBJCFLAGS="$old_OBJCFLAGS" ]) AC_CHECK_HEADERS(dirent.h) AC_CHECK_FUNCS([sysconf gmtime_r localtime_r]) case "$host_os" in amigaos* | morphos*) dnl We don't want fcntl() or nanosleep() on AmigaOS / MorphOS, despite dnl a symbol existing. The reason is that we cannot use fcntl() for dnl sockets and that nanosleep() is yet another function that uses dnl errno, so would need to be passed from the linklib. ;; *) AC_CHECK_HEADERS(fcntl.h) AC_CHECK_FUNCS([fcntl nanosleep]) ;; esac AC_CHECK_HEADERS(xlocale.h) AC_CHECK_FUNCS([strtod_l strtof_l asprintf_l]) AS_IF([test x"$gnu_source" != x"yes" -a \( \ x"$ac_cv_func_strtod_l" = x"yes" -o x"$ac_cv_func_strtof_l" = x"yes" -o \ x"$ac_cv_func_asprintf_l" = x"yes" \)], [ AC_MSG_CHECKING(whether *_l functions need _GNU_SOURCE) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ #include <stdlib.h> #include <stdio.h> #include <locale.h> #ifdef HAVE_XLOCALE_H # include <xlocale.h> #endif ], [ #ifdef HAVE_STRTOD_L (void)strtod_l; #endif #ifdef HAVE_STRTOF_L (void)strtof_l; #endif #ifdef HAVE_ASPRINTF_L (void)asprintf_l; #endif ]) ], [ AC_MSG_RESULT(no) ], [ AC_MSG_RESULT(yes) CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS" ]) ]) dnl This check needs to happen after the above, as _GNU_SOURCE can change the dnl return type. AC_CHECK_FUNCS(strerror_r, [ AC_MSG_CHECKING(for return type of strerror_r) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ #include <stdio.h> #include <string.h> ], [ switch (strerror_r(0, NULL, 0)) { case 0:; } ]) ], [ AC_MSG_RESULT(int) ], [ AC_MSG_RESULT(char *) AC_DEFINE(STRERROR_R_RETURNS_CHARP, 1, [Whether strerror_r returns char *]) ]) ]) AC_CHECK_HEADERS(sys/utsname.h) AC_CHECK_FUNCS(uname) AC_CHECK_FUNC(pipe, [ AC_DEFINE(OF_HAVE_PIPE, 1, [Whether we have pipe()]) ]) AC_ARG_ENABLE(sockets, AS_HELP_STRING([--disable-sockets], [disable socket support])) AS_IF([test x"$enable_sockets" != x"no"], [ AC_DEFINE(OF_HAVE_SOCKETS, 1, [Whether we have sockets]) AC_SUBST(USE_SRCS_SOCKETS, '${SRCS_SOCKETS}') case "$host_os" in amigaos* | morphos*) ;; haiku*) LIBS="$LIBS -lnetwork" ;; mingw*) LIBS="$LIBS -lws2_32 -liphlpapi" ;; *) AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket") ;; esac AC_CHECK_HEADER(sys/socket.h, [ AC_DEFINE(OF_HAVE_SYS_SOCKET_H, 1, [Whether we have sys/socket.h]) ]) AC_CHECK_HEADER(netinet/in.h, [ AC_DEFINE(OF_HAVE_NETINET_IN_H, 1, [Whether we have netinet/in.h]) ]) AC_CHECK_HEADER(netinet/tcp.h, [ AC_DEFINE(OF_HAVE_NETINET_TCP_H, 1, [Whether we have netinet/tcp.h]) ]) AC_CHECK_HEADERS([arpa/inet.h netdb.h]) AC_CHECK_HEADER(netipx/ipx.h, [ AC_DEFINE(OF_HAVE_NETIPX_IPX_H, 1, [Whether we have netipx/ipx.h]) ]) AC_CHECK_HEADER(sys/un.h, [ AC_DEFINE(OF_HAVE_SYS_UN_H, 1, [Whether we have sys/un.h]) ]) AC_CHECK_MEMBER([struct sockaddr_in6.sin6_addr], [ AC_EGREP_CPP(egrep_cpp_yes, [ #ifdef _WIN32 typedef int BOOL; #endif |
︙ | ︙ | |||
1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 | #ifdef AF_INET6 egrep_cpp_yes #endif ], [ AC_DEFINE(OF_HAVE_IPV6, 1, [Whether we have IPv6]) ]) ], [ ], [ #ifdef _WIN32 typedef int BOOL; #endif #ifdef OF_HAVE_NETINET_IN_H # include <netinet/in.h> | > > > | 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 | #ifdef AF_INET6 egrep_cpp_yes #endif ], [ AC_DEFINE(OF_HAVE_IPV6, 1, [Whether we have IPv6]) ]) ], [ dnl Work around a bug in autoconf 2.61 that creates a broken dnl configure if this branch is empty. : ], [ #ifdef _WIN32 typedef int BOOL; #endif #ifdef OF_HAVE_NETINET_IN_H # include <netinet/in.h> |
︙ | ︙ | |||
1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 | egrep_cpp_yes #endif ], [ AC_DEFINE(OF_HAVE_IPX, 1, [Whether we have IPX/SPX]) AC_SUBST(USE_SRCS_IPX, '${SRCS_IPX}') ]) ]) AC_CHECK_FUNCS(paccept accept4, break) AC_CHECK_FUNCS(kqueue1 kqueue, [ AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue]) AC_SUBST(OF_KQUEUE_KERNEL_EVENT_OBSERVER_M, "OFKqueueKernelEventObserver.m") | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 | egrep_cpp_yes #endif ], [ AC_DEFINE(OF_HAVE_IPX, 1, [Whether we have IPX/SPX]) AC_SUBST(USE_SRCS_IPX, '${SRCS_IPX}') ]) ]) AC_CHECK_HEADERS(afunix.h, [ AC_DEFINE(OF_HAVE_AFUNIX_H, 1, [Whether we have afunix.h]) ], [], [ #ifdef _WIN32 # include <winsock2.h> #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 <sys/types.h> #endif #ifdef OF_HAVE_SYS_UN_H # include <sys/un.h> #endif #ifdef _WIN32 # include <winsock2.h> #endif #ifdef HAVE_AFUNIX_H # include <afunix.h> #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_FUNCS(paccept accept4, break) AC_CHECK_FUNCS(kqueue1 kqueue, [ AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue]) AC_SUBST(OF_KQUEUE_KERNEL_EVENT_OBSERVER_M, "OFKqueueKernelEventObserver.m") |
︙ | ︙ | |||
1533 1534 1535 1536 1537 1538 1539 | AC_DEFINE(HAVE_POLL, 1, [Whether we have poll()]) AC_SUBST(OF_POLL_KERNEL_EVENT_OBSERVER_M, "OFPollKernelEventObserver.m") ]) ]) case "$host_os" in | | | < | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < | > | | | | | | > | | > > > > > > > > > > > > > > > > | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 | AC_DEFINE(HAVE_POLL, 1, [Whether we have poll()]) AC_SUBST(OF_POLL_KERNEL_EVENT_OBSERVER_M, "OFPollKernelEventObserver.m") ]) ]) case "$host_os" in amigaos* | mingw* | morphos*) AC_DEFINE(HAVE_SELECT, 1, [Whether we have select() or similar]) AC_SUBST(OF_SELECT_KERNEL_EVENT_OBSERVER_M, "OFSelectKernelEventObserver.m") ;; *) AC_CHECK_HEADERS(sys/select.h) AC_CHECK_FUNC(select, [ AC_DEFINE(HAVE_SELECT, 1, [Whether we have select() or similar]) AC_SUBST(OF_SELECT_KERNEL_EVENT_OBSERVER_M, "OFSelectKernelEventObserver.m") ]) ;; esac 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) AC_LINK_IFELSE([ AC_LANG_PROGRAM([ #include <stdint.h> #include <stdio.h> #include <errno.h> ], [ uint$1_t i = errno; printf("%d", (int)__builtin_bswap$1(i)); ]) ], [ AC_MSG_RESULT(yes) AC_DEFINE(OF_HAVE_BUILTIN_BSWAP$1, 1, [Whether we have __builtin_bswap$1]) ], [ AC_MSG_RESULT(no) ]) ]) CHECK_BUILTIN_BSWAP(16) CHECK_BUILTIN_BSWAP(32) CHECK_BUILTIN_BSWAP(64) case "$host_os" in darwin*) AC_MSG_CHECKING(whether we are compiling for macOS) AC_EGREP_CPP(egrep_cpp_yes, [ #include <TargetConditionals.h> #if (!defined(TARGET_OS_IPHONE) || !TARGET_OS_IPHONE) && \ (!defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR) 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" ]) ;; mingw*) have_subprocesses="yes" ;; msdosdjgpp*) have_subprocesses="no" ;; *) AC_HEADER_SYS_WAIT AC_CHECK_FUNCS(kill) AC_CHECK_FUNCS(posix_spawnp, [ AS_IF([test x"$ac_cv_func_kill" = x"yes"], [ have_subprocesses="yes" AC_CHECK_HEADERS(spawn.h) ]) ], [ AC_CHECK_FUNCS([vfork dup2 execvp _exit], [ AS_IF([test x"$ac_cv_func_vfork" = x"yes" \ -a x"$ac_cv_func_pipe" = x"yes" \ -a x"$ac_cv_func_dup2" = x"yes" \ -a x"$ac_cv_func_execvp" = x"yes" \ -a x"$ac_cv_func_kill" = x"yes" \ -a x"$ac_cv_func__exit" = x"yes"], [ have_subprocesses="yes" ]) ], [ break ]) ]) ;; esac AS_IF([test x"$have_subprocesses" = x"yes"], [ AC_SUBST(OF_SUBPROCESS_M, "OFSubprocess.m") AC_DEFINE(OF_HAVE_SUBPROCESSES, 1, [Whether we have subprocesses]) ]) AC_CHECK_HEADERS_ONCE([complex.h sys/ioctl.h sys/ttycom.h]) AC_CHECK_FUNCS(isatty) AC_CHECK_FUNC(pledge, [ AC_DEFINE(OF_HAVE_PLEDGE, 1, [Whether we have pledge()]) |
︙ | ︙ | |||
1656 1657 1658 1659 1660 1661 1662 | dnl This needs to be after all other header checks, as they include unistd.h, dnl which in old glibc versions uses __block. This is worked around in the code dnl by providing a wrapper for unistd.h which takes care of this. AC_MSG_CHECKING(whether Objective C compiler supports blocks) old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -Xclang -fblocks" | | > | | > | > | | | | | | | | | | | | | | | | > | > | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | > | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | > | | > | | | | | | | | | | | > > > > > | > | | | | | | | | | | | | | | | | | | | | | | | | | > | | > | | | | > | | | | | | < < < > > > > | 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 | dnl This needs to be after all other header checks, as they include unistd.h, dnl which in old glibc versions uses __block. This is worked around in the code dnl by providing a wrapper for unistd.h which takes care of this. AC_MSG_CHECKING(whether Objective C compiler supports blocks) old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -Xclang -fblocks" AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([], [ int (^foo)(int bar); foo = ^ (int bar) { return 0; } ]) ], [ OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS -Xclang -fblocks" AC_SUBST(OF_BLOCK_TESTS_M, "OFBlockTests.m") AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) OBJCFLAGS="$old_OBJCFLAGS" ]) AS_IF([test x"$GOBJC" = x"yes"], [ OBJCFLAGS="$OBJCFLAGS -Wwrite-strings -Wpointer-arith -Werror" AC_MSG_CHECKING(whether we need -Wno-strict-aliasing due to GCC bugs) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ #ifdef __has_attribute # if __has_attribute(objc_root_class) __attribute__((__objc_root_class__)) # endif #endif @interface Foo { struct objc_class *_isa; } @end static struct { struct objc_class *_isa; } object; ], [ Foo *test = (Foo *)&object; (void)test; /* Get rid of unused variable warning */ ]) ], [ AC_MSG_RESULT(no) ], [ AC_MSG_RESULT(yes) OBJCFLAGS="$OBJCFLAGS -Wno-strict-aliasing" ]) AC_MSG_CHECKING( whether we need -Wno-unused-property-ivar due to Clang bugs) AC_COMPILE_IFELSE([ AC_LANG_SOURCE([ #ifdef __has_attribute # if __has_attribute(objc_root_class) __attribute__((__objc_root_class__)) # endif #endif @interface Foo { struct objc_class *_isa; Foo *_foo; } @property (readonly, nonatomic) Foo *foo; + (Foo *)foo; @end @implementation Foo @synthesize foo = _foo; + (Foo *)foo { return (Foo *)0; } @end ]) ], [ AC_MSG_RESULT(no) ], [ AC_MSG_RESULT(yes) OBJCFLAGS="$OBJCFLAGS -Wno-unused-property-ivar" ]) old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -Wcast-align" AC_MSG_CHECKING(whether -Wcast-align is buggy) AC_COMPILE_IFELSE([ AC_LANG_SOURCE([ #ifdef __has_attribute # if __has_attribute(objc_root_class) __attribute__((__objc_root_class__)) # endif #endif @interface Foo { struct objc_class *_isa; } @end @implementation Foo - (void)foo { struct objc_class *c = _isa; (void)c; } @end ]) ], [ AC_MSG_RESULT(no) ], [ AC_MSG_RESULT(yes) OBJCFLAGS="$old_OBJCFLAGS" ]) old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -Wunreachable-code" AC_MSG_CHECKING(whether -Wunreachable-code can be used) AC_COMPILE_IFELSE([ AC_LANG_SOURCE([[ #include <stdlib.h> struct objc_selector; typedef const struct objc_selector *SEL; #ifdef __has_attribute # if __has_attribute(objc_root_class) __attribute__((__objc_root_class__)) # endif #endif @interface Object - (void)doesNotRecognizeSelector: (SEL)selector #ifdef __clang__ __attribute__((__noreturn__)) #endif ; - (void)dealloc; @end @interface Foo: Object @end void test(void) { if (sizeof(int) == 4) __asm__ (""); else if (sizeof(int) == 8) __asm__ (""); else abort(); } /* * Unfortunately, this cannot be shorter, as it only * works when it is used inside a macro. */ #ifdef __clang__ # define OF_DEALLOC_UNSUPPORTED \ [self doesNotRecognizeSelector: _cmd]; \ \ abort(); \ \ _Pragma("clang diagnostic push ignore \ \"-Wunreachable-code\""); \ [super dealloc]; \ _Pragma("clang diagnostic pop"); #else # define OF_DEALLOC_UNSUPPORTED \ [self doesNotRecognizeSelector: _cmd]; \ \ abort(); \ \ [super dealloc]; #endif @implementation Foo - (void)dealloc { OF_DEALLOC_UNSUPPORTED } @end ]]) ], [ AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) OBJCFLAGS="$old_OBJCFLAGS" ]) old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -Wdocumentation" AC_MSG_CHECKING(whether -Wdocumentation works correctly) AC_COMPILE_IFELSE([ AC_LANG_SOURCE([ /** * @class Test conftest.m conftest.m */ #ifdef __has_attribute # if __has_attribute(objc_root_class) __attribute__((__objc_root_class__)) # endif #endif @interface Test @end /** * @struct Foo conftest.m conftest.m */ typedef struct {} Foo; ]) ], [ AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) OBJCFLAGS="$old_OBJCFLAGS" ]) AS_IF([test x"$check_pedantic" = x"yes"], [ old_OBJCFLAGS="$OBJCFLAGS" OBJCFLAGS="$OBJCFLAGS -pedantic" AC_MSG_CHECKING(whether -pedantic is buggy) AC_COMPILE_IFELSE([ AC_LANG_SOURCE([ #include <stdlib.h> #include <assert.h> #ifdef __has_attribute # if __has_attribute(objc_root_class) __attribute__((__objc_root_class__)) # endif #endif @interface Foo { void *foo; } @end @interface Bar: Foo - (void)assert; @end @implementation Bar - (void)assert { /* * Some versions of glibc break with * -pedantic when using assert. */ assert(1); } @end ]) ], [ AC_MSG_RESULT(no) ], [ AC_MSG_RESULT(yes) OBJCFLAGS="$old_OBJCFLAGS" ]) ]) AS_IF([test x"$ac_cv_header_complex_h" = x"yes"], [ AC_MSG_CHECKING(whether we need -Wno-gnu-imaginary-constant) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([ #include <complex.h> ], [ complex float f = 0.5 + 0.5 * I; (void)f; ]) ], [ AC_MSG_RESULT(no) ], [ AC_MSG_RESULT(yes) OBJCFLAGS="$OBJCFLAGS -Wno-gnu-imaginary-constant" ]) ]) ]) AS_IF([test x"$cross_compiling" = x"yes"], [ AC_SUBST(BIN_PREFIX, "${host_alias}-") case "$host" in i?86-*-mingw*) AC_CHECK_PROG(WINE, wine, wine) ;; x86_64-*-mingw*) AC_CHECK_PROG(WINE, wine64, wine64) ;; esac AS_IF([test x"$WINE" != x""], [ AC_SUBST(WRAPPER, "$WINE") ]) AS_IF([test x"$with_wii" = x"yes"], [ dnl Keep this lowercase, as WIILOAD is a variable used by dnl wiiload and thus likely already set by the user to something dnl that is not the path of the wiiload binary. AC_CHECK_PROG(wiiload, wiiload, wiiload) AS_IF([test x"$wiiload" != x""], [ AC_SUBST(WRAPPER, "$wiiload") ]) ]) ]) AC_ARG_WITH(fish_completions, AS_HELP_STRING([--with-fish-completions], [install completions for the fish shell])) AS_IF([test x"$with_fish_completions" = x""], [ AC_CHECK_PROG(FISH, fish, fish) AS_IF([test x"$FISH" != x""], [with_fish_completions="yes"]) ]) AS_IF([test x"$with_fish_completions" = x"yes"], [ AC_SUBST(FISH_COMPLETIONS, fish) ]) dnl We don't call AC_PROG_CPP, but only AC_PROG_OBJCPP and set CPP to OBJCPP dnl and add OBJCPPFLAGS to CPPFLAGS, thus we need to AC_SUBST these ourself. AC_SUBST(CPP) |
︙ | ︙ |
Modified extra.mk.in from [be5acfe5fa] to [8ae8820dcd].
1 2 3 | OBJFW_SHARED_LIB = @OBJFW_SHARED_LIB@ OBJFW_STATIC_LIB = @OBJFW_STATIC_LIB@ OBJFW_FRAMEWORK = @OBJFW_FRAMEWORK@ | | | | > > > > < < < < < < < < < < < | < | > | > > < | > < > > > < > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | OBJFW_SHARED_LIB = @OBJFW_SHARED_LIB@ OBJFW_STATIC_LIB = @OBJFW_STATIC_LIB@ OBJFW_FRAMEWORK = @OBJFW_FRAMEWORK@ OBJFW_LIB_MAJOR = 0 OBJFW_LIB_MINOR = 0 OBJFW_LIB_MAJOR_MINOR = ${OBJFW_LIB_MAJOR}.${OBJFW_LIB_MINOR} OBJFWRT_SHARED_LIB = @OBJFWRT_SHARED_LIB@ OBJFWRT_STATIC_LIB = @OBJFWRT_STATIC_LIB@ OBJFWRT_FRAMEWORK = @OBJFWRT_FRAMEWORK@ OBJFWRT_AMIGA_LIB = @OBJFWRT_AMIGA_LIB@ OBJFWRT_LIB_MAJOR = 0 OBJFWRT_LIB_MINOR = 0 OBJFWRT_LIB_MAJOR_MINOR = ${OBJFWRT_LIB_MAJOR}.${OBJFWRT_LIB_MINOR} 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_LIB_A = @ENCODINGS_LIB_A@ ENCODINGS_SRCS = @ENCODINGS_SRCS@ EXCEPTIONS_A = @EXCEPTIONS_A@ EXCEPTIONS_LIB_A = @EXCEPTIONS_LIB_A@ FISH_COMPLETIONS = @FISH_COMPLETIONS@ FORWARDING_A = @FORWARDING_A@ FORWARDING_LIB_A = @FORWARDING_LIB_A@ LIBBASES_M = @LIBBASES_M@ LIBOBJFWRT_DEP = @LIBOBJFWRT_DEP@ LIBOBJFWRT_DEP_LVL2 = @LIBOBJFWRT_DEP_LVL2@ LIBOBJFW_DEP = @LIBOBJFW_DEP@ LIBOBJFW_DEP_LVL2 = @LIBOBJFW_DEP_LVL2@ LINKLIB = @LINKLIB@ LOOKUP_ASM_A = @LOOKUP_ASM_A@ LOOKUP_ASM_AMIGALIB_A = @LOOKUP_ASM_AMIGALIB_A@ LOOKUP_ASM_LIB_A = @LOOKUP_ASM_LIB_A@ MAP_LDFLAGS = @MAP_LDFLAGS@ OBJC_SYNC = @OBJC_SYNC@ OFARC = @OFARC@ OFDNS = @OFDNS@ OFHASH = @OFHASH@ OFHTTP = @OFHTTP@ OFHTTP_LIBS = @OFHTTP_LIBS@ OF_BLOCK_TESTS_M = @OF_BLOCK_TESTS_M@ OF_EPOLL_KERNEL_EVENT_OBSERVER_M = @OF_EPOLL_KERNEL_EVENT_OBSERVER_M@ 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@ RUNTIME_ARC_TESTS_M = @RUNTIME_ARC_TESTS_M@ RUNTIME_AUTORELEASE_M = @RUNTIME_AUTORELEASE_M@ RUNTIME_FRAMEWORK_LIBS = @RUNTIME_FRAMEWORK_LIBS@ RUNTIME_INSTANCE_M = @RUNTIME_INSTANCE_M@ RUNTIME_LIBS = @RUNTIME_LIBS@ SFDC_INLINE_H = @SFDC_INLINE_H@ SFDC_TARGET = @SFDC_TARGET@ SFD_FILE = @SFD_FILE@ TESTPLUGIN = @TESTPLUGIN@ TESTPLUGIN_LIBS = @TESTPLUGIN_LIBS@ TESTS_LIBS = @TESTS_LIBS@ TESTS_STATIC_LIB = @TESTS_STATIC_LIB@ 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@ |
Added generators/library/FuncArrayGenerator.h version [2d0edf7996].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFStream.h" #import "OFXMLElement.h" @interface FuncArrayGenerator: OFObject { OFXMLElement *_library; OFStream *_include; } - (instancetype)initWithLibrary: (OFXMLElement *)library include: (OFStream *)include; - (void)generate; @end |
Added generators/library/FuncArrayGenerator.m version [4ed090453c].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFArray.h" #import "OFXMLAttribute.h" #import "FuncArrayGenerator.h" #import "OFInvalidFormatException.h" #import "OFUnsupportedVersionException.h" #import "copyright.h" @implementation FuncArrayGenerator - (instancetype)initWithLibrary: (OFXMLElement *)library include: (OFStream *)include { self = [super init]; @try { OFXMLAttribute *version; if (![library.name isEqual: @"amiga-library"] || library.namespace != nil) @throw [OFInvalidFormatException exception]; if ((version = [library attributeForName: @"version"]) == nil) @throw [OFInvalidFormatException exception]; if (![version.stringValue isEqual: @"1.0"]) @throw [OFUnsupportedVersionException exceptionWithVersion: version.stringValue]; _library = [library retain]; _include = [include retain]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_library release]; [_include release]; [super dealloc]; } - (void)generate { [_include writeString: COPYRIGHT]; [_include writeString: @"/* This file is automatically generated from amiga-library.xml */" @"\n\n"]; for (OFXMLElement *function in [_library elementsForName: @"function"]) [_include writeFormat: @"(CONST_APTR)glue_%@,\n", [function attributeForName: @"name"].stringValue]; } @end |
Added generators/library/GlueGenerator.h version [df3f9366c5].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFStream.h" #import "OFXMLElement.h" @interface GlueGenerator: OFObject { OFXMLElement *_library; OFStream *_header, *_impl; } - (instancetype)initWithLibrary: (OFXMLElement *)library header: (OFStream *)header implementation: (OFStream *)implementation; - (void)generate; @end |
Added generators/library/GlueGenerator.m version [a4f73aa06c].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFArray.h" #import "OFXMLAttribute.h" #import "GlueGenerator.h" #import "OFInvalidFormatException.h" #import "OFUnsupportedVersionException.h" #import "copyright.h" @implementation GlueGenerator - (instancetype)initWithLibrary: (OFXMLElement *)library header: (OFStream *)header implementation: (OFStream *)impl { self = [super init]; @try { OFXMLAttribute *version; if (![library.name isEqual: @"amiga-library"] || library.namespace != nil) @throw [OFInvalidFormatException exception]; if ((version = [library attributeForName: @"version"]) == nil) @throw [OFInvalidFormatException exception]; if (![version.stringValue isEqual: @"1.0"]) @throw [OFUnsupportedVersionException exceptionWithVersion: version.stringValue]; _library = [library retain]; _header = [header retain]; _impl = [impl retain]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_library release]; [_header release]; [_impl release]; [super dealloc]; } - (void)generate { [_header writeString: COPYRIGHT]; [_impl writeString: COPYRIGHT]; [_header writeString: @"/* This file is automatically generated from amiga-library.xml */" @"\n\n"]; [_impl writeString: @"/* This file is automatically generated from amiga-library.xml */" @"\n\n" @"#include \"config.h\"\n" @"\n" @"#import \"amiga-glue.h\"\n" @"\n"]; for (OFXMLElement *include in [_library elementsForName: @"include"]) [_header writeFormat: @"#import \"%@\"\n", include.stringValue]; [_header writeString: @"\n" @"#ifdef OF_AMIGAOS_M68K\n" @"# define PPC_PARAMS(...) (void)\n" @"# define M68K_ARG(type, name, reg)\t\t\\\n" @"\tregister type reg##name __asm__(#reg);\t\\\n" @"\ttype name = reg##name;\n" @"#else\n" @"# define PPC_PARAMS(...) (__VA_ARGS__)\n" @"# define M68K_ARG(...)\n" @"#endif\n" @"\n"]; [_impl writeString: @"#ifdef OF_MORPHOS\n" @"/* All __saveds functions in this file need to use the SysV " @"ABI */\n" @"__asm__ (\n" @" \".section .text\\n\"\n" @" \".align 2\\n\"\n" @" \"__restore_r13:\\n\"\n" @" \"\tlwz\t%r13, 44(%r12)\\n\"\n" @" \"\tblr\\n\"\n" @");\n" @"#endif\n"]; for (OFXMLElement *function in [_library elementsForName: @"function"]) { OFString *name = [function attributeForName: @"name"].stringValue; OFString *returnType = [function attributeForName: @"return-type"].stringValue; OFArray OF_GENERIC(OFXMLElement *) *arguments = [function elementsForName: @"argument"]; size_t argumentIndex; if (returnType == nil) returnType = @"void"; [_header writeFormat: @"extern %@%@glue_%@", returnType, (![returnType hasSuffix: @"*"] ? @" " : @""), name]; [_impl writeFormat: @"\n" @"%@ __saveds\n" @"glue_%@", returnType, name]; if (arguments.count > 0) { [_header writeString: @" PPC_PARAMS("]; [_impl writeString: @" PPC_PARAMS("]; } else { [_header writeString: @"(void"]; [_impl writeString: @"(void"]; } argumentIndex = 0; for (OFXMLElement *argument in arguments) { OFString *argName = [argument attributeForName: @"name"].stringValue; OFString *argType = [argument attributeForName: @"type"].stringValue; if (argumentIndex++ > 0) { [_header writeString: @", "]; [_impl writeString: @", "]; } [_header writeString: argType]; [_impl writeString: argType]; if (![argType hasSuffix: @"*"]) { [_header writeString: @" "]; [_impl writeString: @" "]; } [_header writeString: argName]; [_impl writeString: argName]; } [_header writeString: @");\n"]; [_impl writeString: @")\n{\n"]; for (OFXMLElement *argument in arguments) { OFString *argName = [argument attributeForName: @"name"].stringValue; OFString *argType = [argument attributeForName: @"type"].stringValue; OFString *m68kReg = [argument attributeForName: @"m68k-reg"].stringValue; [_impl writeFormat: @"\tM68K_ARG(%@, %@, %@)\n", argType, argName, m68kReg]; } if (arguments.count > 0) [_impl writeString: @"\n"]; if (![returnType isEqual: @"void"]) [_impl writeString: @"\treturn "]; else [_impl writeString: @"\t"]; [_impl writeFormat: @"%@(", name]; argumentIndex = 0; for (OFXMLElement *argument in arguments) { OFString *argName = [argument attributeForName: @"name"].stringValue; if (argumentIndex++ > 0) [_impl writeString: @", "]; [_impl writeString: argName]; } [_impl writeString: @");\n}\n"]; } } @end |
Added generators/library/LibraryGenerator.m version [0e687972e3].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFApplication.h" #import "OFFile.h" #import "OFFileManager.h" #import "OFURL.h" #import "OFXMLElement.h" #import "FuncArrayGenerator.h" #import "GlueGenerator.h" #import "LinkLibGenerator.h" @interface LibraryGenerator: OFObject <OFApplicationDelegate> @end OF_APPLICATION_DELEGATE(LibraryGenerator) @implementation LibraryGenerator - (void)applicationDidFinishLaunching { OFURL *sourcesURL = [[OFFileManager defaultManager].currentDirectoryURL URLByAppendingPathComponent: @"../../src"]; OFURL *runtimeLibraryURL = [sourcesURL URLByAppendingPathComponent: @"runtime/amiga-library.xml"]; OFURL *runtimeLinkLibURL = [sourcesURL URLByAppendingPathComponent: @"runtime/linklib/linklib.m"]; OFURL *runtimeGlueHeaderURL = [sourcesURL URLByAppendingPathComponent: @"runtime/amiga-glue.h"]; OFURL *runtimeGlueURL = [sourcesURL URLByAppendingPathComponent: @"runtime/amiga-glue.m"]; OFURL *runtimeFuncArrayURL = [sourcesURL URLByAppendingPathComponent: @"runtime/amiga-funcarray.inc"]; OFXMLElement *runtimeLibrary = [OFXMLElement elementWithStream: [OFFile fileWithPath: runtimeLibraryURL.fileSystemRepresentation mode: @"r"]]; OFFile *runtimeLinkLib = [OFFile fileWithPath: runtimeLinkLibURL.fileSystemRepresentation mode: @"w"]; OFFile *runtimeGlueHeader = [OFFile fileWithPath: runtimeGlueHeaderURL.fileSystemRepresentation mode: @"w"]; OFFile *runtimeGlue = [OFFile fileWithPath: runtimeGlueURL.fileSystemRepresentation mode: @"w"]; OFFile *runtimeFuncArray = [OFFile fileWithPath: runtimeFuncArrayURL.fileSystemRepresentation mode: @"w"]; LinkLibGenerator *runtimeLinkLibGenerator = [[[LinkLibGenerator alloc] initWithLibrary: runtimeLibrary implementation: runtimeLinkLib] autorelease]; GlueGenerator *runtimeGlueGenerator = [[[GlueGenerator alloc] initWithLibrary: runtimeLibrary header: runtimeGlueHeader implementation: runtimeGlue] autorelease]; FuncArrayGenerator *runtimeFuncArrayGenerator; runtimeFuncArrayGenerator = [[[FuncArrayGenerator alloc] initWithLibrary: runtimeLibrary include: runtimeFuncArray] autorelease]; [runtimeLinkLibGenerator generate]; [runtimeGlueGenerator generate]; [runtimeFuncArrayGenerator generate]; [OFApplication terminate]; } @end |
Added generators/library/LinkLibGenerator.h version [58647bf17f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFStream.h" #import "OFXMLElement.h" @interface LinkLibGenerator: OFObject { OFXMLElement *_library; OFStream *_impl; } - (instancetype)initWithLibrary: (OFXMLElement *)library implementation: (OFStream *)impl; - (void)generate; @end |
Added generators/library/LinkLibGenerator.m version [e9161f0524].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFArray.h" #import "OFXMLAttribute.h" #import "LinkLibGenerator.h" #import "OFInvalidFormatException.h" #import "OFUnsupportedVersionException.h" #import "copyright.h" @implementation LinkLibGenerator - (instancetype)initWithLibrary: (OFXMLElement *)library implementation: (OFStream *)impl { self = [super init]; @try { OFXMLAttribute *version; if (![library.name isEqual: @"amiga-library"] || library.namespace != nil) @throw [OFInvalidFormatException exception]; if ((version = [library attributeForName: @"version"]) == nil) @throw [OFInvalidFormatException exception]; if (![version.stringValue isEqual: @"1.0"]) @throw [OFUnsupportedVersionException exceptionWithVersion: version.stringValue]; _library = [library retain]; _impl = [impl retain]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_library release]; [_impl release]; [super dealloc]; } - (void)generate { OFString *libBase = [_library attributeForName: @"base"].stringValue; OFArray OF_GENERIC(OFXMLElement *) *functions; size_t funcIndex = 0; [_impl writeString: COPYRIGHT]; [_impl writeString: @"/* This file is automatically generated from amiga-library.xml */" @"\n\n" @"#include \"config.h\"\n" @"\n"]; for (OFXMLElement *include in [_library elementsForName: @"include"]) [_impl writeFormat: @"#import \"%@\"\n", include.stringValue]; [_impl writeFormat: @"\n" @"extern struct Library *%@;\n" @"\n", libBase]; functions = [_library elementsForName: @"function"]; for (OFXMLElement *function in functions) { OFString *name = [function attributeForName: @"name"].stringValue; OFString *returnType = [function attributeForName: @"return-type"].stringValue; OFArray OF_GENERIC(OFXMLElement *) *arguments = [function elementsForName: @"argument"]; size_t argumentIndex; if (returnType == nil) returnType = @"void"; [_impl writeFormat: @"%@\n%@(", returnType, name]; argumentIndex = 0; for (OFXMLElement *argument in [function elementsForName: @"argument"]) { OFString *argName = [argument attributeForName: @"name"].stringValue; OFString *argType = [argument attributeForName: @"type"].stringValue; if (argumentIndex++ > 0) [_impl writeString: @", "]; [_impl writeString: argType]; if (![argType hasSuffix: @"*"]) [_impl writeString: @" "]; [_impl writeString: argName]; } [_impl writeFormat: @")\n" @"{\n" @"#if defined(OF_AMIGAOS_M68K)\n" @"\tregister struct Library *a6 __asm__(\"a6\") = %@;\n" @"\t(void)a6;\n" @"\t", libBase]; if (![returnType isEqual: @"void"]) [_impl writeString: @"return "]; [_impl writeString: @"(("]; [_impl writeString: returnType]; if (![returnType hasSuffix: @"*"]) [_impl writeString: @" "]; [_impl writeString: @"(*)("]; argumentIndex = 0; for (OFXMLElement *argument in arguments) { OFString *argType = [argument attributeForName: @"type"].stringValue; OFString *m68kReg = [argument attributeForName: @"m68k-reg"].stringValue; if (argumentIndex++ > 0) [_impl writeString: @", "]; [_impl writeString: argType]; if (![argType hasSuffix: @"*"]) [_impl writeString: @" "]; [_impl writeFormat: @"__asm__(\"%@\")", m68kReg]; } [_impl writeFormat: @"))(((uintptr_t)%@) - %zu))(", libBase, 30 + funcIndex * 6]; argumentIndex = 0; for (OFXMLElement *argument in [function elementsForName: @"argument"]) { OFString *argName = [argument attributeForName: @"name"].stringValue; if (argumentIndex++ > 0) [_impl writeString: @", "]; [_impl writeString: argName]; } [_impl writeFormat: @");\n" @"#elif defined(OF_MORPHOS)\n" @"\t__asm__ __volatile__ (\n" @"\t \"mr\t\t%%%%r12, %%0\"\n" @"\t :: \"r\"(%@) : \"r12\"\n" @"\t);\n" @"\n" @"\t", libBase, libBase]; if (![returnType isEqual: @"void"]) [_impl writeString: @"return "]; [_impl writeString: @"__extension__ (("]; [_impl writeString: returnType]; if (![returnType hasSuffix: @"*"]) [_impl writeString: @" "]; [_impl writeString: @"(*)("]; argumentIndex = 0; for (OFXMLElement *argument in arguments) { OFString *argType = [argument attributeForName: @"type"].stringValue; if (argumentIndex++ > 0) [_impl writeString: @", "]; [_impl writeString: argType]; } [_impl writeFormat: @"))*(void **)(((uintptr_t)%@) - %zu))(", libBase, 28 + funcIndex * 6]; argumentIndex = 0; for (OFXMLElement *argument in [function elementsForName: @"argument"]) { OFString *argName = [argument attributeForName: @"name"].stringValue; if (argumentIndex++ > 0) [_impl writeString: @", "]; [_impl writeString: argName]; } [_impl writeString: @");\n" @"#endif\n"]; if ([function attributeForName: @"noreturn"] != nil) [_impl writeString: @"\n\tOF_UNREACHABLE\n"]; [_impl writeString: @"}\n"]; if (++funcIndex < functions.count) [_impl writeString: @"\n"]; } } @end |
Added generators/library/Makefile version [b62d874949].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | include ../../extra.mk PROG_NOINST = gen_libraries${PROG_SUFFIX} SRCS = FuncArrayGenerator.m \ GlueGenerator.m \ LibraryGenerator.m \ LinkLibGenerator.m include ../../buildsys.mk .PHONY: run run: all rm -f libobjfw.so.${OBJFW_LIB_MAJOR} rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} rm -f objfw${OBJFW_LIB_MAJOR}.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR} rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib rm -f ${OBJFWRT_AMIGA_LIB} if test -f ../../src/libobjfw.so; then \ ${LN_S} ../../src/libobjfw.so libobjfw.so.${OBJFW_LIB_MAJOR}; \ ${LN_S} ../../src/libobjfw.so \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ elif test -f ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/objfw${OBJFW_LIB_MAJOR}.dll; then \ ${LN_S} ../../src/objfw${OBJFW_LIB_MAJOR}.dll \ objfw${OBJFW_LIB_MAJOR}.dll; \ fi if test -f ../../src/libobjfw.dylib; then \ ${LN_S} ../../src/libobjfw.dylib \ libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/libobjfwrt.so; then \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ elif test -f ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll; then \ ${LN_S} ../../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll \ objfwrt${OBJFWRT_LIB_MAJOR}.dll; \ fi if test -f ../../src/runtime/libobjfwrt.dylib; then \ ${LN_S} ../../src/runtime/libobjfwrt.dylib \ libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/${OBJFWRT_AMIGA_LIB}; then \ ${LN_S} ../../src/runtime/${OBJFWRT_AMIGA_LIB} \ ${OBJFWRT_AMIGA_LIB}; \ fi LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ DYLD_FRAMEWORK_PATH=../../src:../../src/runtime$${DYLD_FRAMEWORK_PATH+:}$$DYLD_FRAMEWORK_PATH \ DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ LIBRARY_PATH=.$${LIBRARY_PATH+:}$$LIBRARY_PATH \ ASAN_OPTIONS=allocator_may_return_null=1 \ ${WRAPPER} ./${PROG_NOINST}; EXIT=$$?; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR}; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ rm -f objfw${OBJFW_LIB_MAJOR}.dll; \ rm -f libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll; \ rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ exit $$EXIT CPPFLAGS += -I../../src -I../../src/exceptions -I../../src/runtime -I../.. LIBS := -L../../src -lobjfw -L../../src/runtime ${RUNTIME_LIBS} ${LIBS} LD = ${OBJC} |
Added generators/library/copyright.h version [c0b22b50fd].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFString.h" #define COPYRIGHT \ @"/*\n" \ @" * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im>\n" \ @" *\n" \ @" * All rights reserved.\n" \ @" *\n" \ @" * This file is part of ObjFW. It may be distributed under the terms " \ @"of the\n" \ @" * Q Public License 1.0, which can be found in the file LICENSE.QPL " \ @"included in\n" \ @" * the packaging of this file.\n" \ @" *\n" \ @" * Alternatively, it may be distributed under the terms of the GNU " \ @"General\n" \ @" * Public License, either version 2 or 3, which can be found in the " \ @"file\n" \ @" * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the " \ @"packaging of this\n" \ @" * file.\n" \ @" */\n" \ @"\n" |
Renamed and modified generators/Makefile [0e25880b06] to generators/unicode/Makefile [9009fb89e7].
|
| | > > | > | | | | | | | | > | | | | | | | | | > | | | | | | > | > < | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | include ../../extra.mk PROG_NOINST = gen_tables${PROG_SUFFIX} SRCS = TableGenerator.m include ../../buildsys.mk .PHONY: run run: all rm -f libobjfw.so.${OBJFW_LIB_MAJOR} rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} rm -f objfw${OBJFW_LIB_MAJOR}.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR} rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib rm -f ${OBJFWRT_AMIGA_LIB} if test -f ../../src/libobjfw.so; then \ ${LN_S} ../../src/libobjfw.so libobjfw.so.${OBJFW_LIB_MAJOR}; \ ${LN_S} ../../src/libobjfw.so \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ elif test -f ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/objfw${OBJFW_LIB_MAJOR}.dll; then \ ${LN_S} ../../src/objfw${OBJFW_LIB_MAJOR}.dll \ objfw${OBJFW_LIB_MAJOR}.dll; \ fi if test -f ../../src/libobjfw.dylib; then \ ${LN_S} ../../src/libobjfw.dylib \ libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/libobjfwrt.so; then \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ elif test -f ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll; then \ ${LN_S} ../../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll \ objfwrt${OBJFWRT_LIB_MAJOR}.dll; \ fi if test -f ../../src/runtime/libobjfwrt.dylib; then \ ${LN_S} ../../src/runtime/libobjfwrt.dylib \ libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/${OBJFWRT_AMIGA_LIB}; then \ ${LN_S} ../../src/runtime/${OBJFWRT_AMIGA_LIB} \ ${OBJFWRT_AMIGA_LIB}; \ fi LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ DYLD_FRAMEWORK_PATH=../../src:../../src/runtime$${DYLD_FRAMEWORK_PATH+:}$$DYLD_FRAMEWORK_PATH \ DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ LIBRARY_PATH=.$${LIBRARY_PATH+:}$$LIBRARY_PATH \ ASAN_OPTIONS=allocator_may_return_null=1 \ ${WRAPPER} ./${PROG_NOINST}; EXIT=$$?; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR}; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ rm -f objfw${OBJFW_LIB_MAJOR}.dll; \ rm -f libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll; \ rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ exit $$EXIT CPPFLAGS += -I../../src -I../../src/exceptions -I../../src/runtime -I../.. LIBS := -L../../src -lobjfw -L../../src/runtime ${RUNTIME_LIBS} ${LIBS} LD = ${OBJC} |
Renamed and modified generators/TableGenerator.h [1738fc87e6] to generators/unicode/TableGenerator.h [d5ba8e12b8].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | @class OFString; @interface TableGenerator: OFObject <OFApplicationDelegate, OFHTTPClientDelegate> { OFHTTPClient *_HTTPClient; | | | | | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | @class OFString; @interface TableGenerator: OFObject <OFApplicationDelegate, OFHTTPClientDelegate> { OFHTTPClient *_HTTPClient; OFUnichar _uppercaseTable[0x110000]; OFUnichar _lowercaseTable[0x110000]; OFUnichar _titlecaseTable[0x110000]; OFUnichar _caseFoldingTable[0x110000]; OFString *_decompositionTable[0x110000]; OFString *_decompositionCompatTable[0x110000]; char _uppercaseTableUsed[0x1100]; char _lowercaseTableUsed[0x1100]; char _titlecaseTableUsed[0x1100]; char _caseFoldingTableUsed[0x1100]; char _decompositionTableUsed[0x1100]; char _decompositionCompatTableUsed[0x1100]; size_t _uppercaseTableSize; size_t _lowercaseTableSize; size_t _titlecaseTableSize; size_t _caseFoldingTableSize; size_t _decompositionTableSize; size_t _decompositionCompatTableSize; enum { stateUnicodeData, stateCaseFolding } _state; } - (void)parseUnicodeData: (OFHTTPResponse *)response; - (void)parseCaseFolding: (OFHTTPResponse *)response; - (void)applyDecompositionRecursivelyForTable: (OFString *[0x110000])table; - (void)writeFiles; - (void)writeTablesToFile: (OFString *)path; - (void)writeHeaderToFile: (OFString *)path; @end |
Renamed and modified generators/TableGenerator.m [e134a30212] to generators/unicode/TableGenerator.m [442fb49647].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | #import "OFStdIOStream.h" #import "OFOutOfRangeException.h" #import "TableGenerator.h" #import "copyright.h" | | | | | | < > | | | | | | | | | | | | | | | | | | | | | | | | | | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | #import "OFStdIOStream.h" #import "OFOutOfRangeException.h" #import "TableGenerator.h" #import "copyright.h" static OFString *const unicodeDataURL = @"http://www.unicode.org/Public/UNIDATA/UnicodeData.txt"; static OFString *const caseFoldingURL = @"http://www.unicode.org/Public/UNIDATA/CaseFolding.txt"; OF_APPLICATION_DELEGATE(TableGenerator) @implementation TableGenerator - (instancetype)init { self = [super init]; @try { _HTTPClient = [[OFHTTPClient alloc] init]; _HTTPClient.delegate = self; _uppercaseTableSize = SIZE_MAX; _lowercaseTableSize = SIZE_MAX; _titlecaseTableSize = SIZE_MAX; _caseFoldingTableSize = SIZE_MAX; _decompositionTableSize = SIZE_MAX; _decompositionCompatTableSize = SIZE_MAX; } @catch (id e) { [self release]; @throw e; } return self; } - (void)applicationDidFinishLaunching { OFHTTPRequest *request; [OFStdOut writeString: @"Downloading UnicodeData.txt…"]; _state = stateUnicodeData; request = [OFHTTPRequest requestWithURL: [OFURL URLWithString: unicodeDataURL]]; [_HTTPClient asyncPerformRequest: request]; } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response exception: (id)exception { if (exception != nil) @throw exception; [OFStdOut writeLine: @" done"]; switch (_state) { case stateUnicodeData: [self parseUnicodeData: response]; break; case stateCaseFolding: [self parseCaseFolding: response]; break; } } - (void)parseUnicodeData: (OFHTTPResponse *)response { OFString *line; OFHTTPRequest *request; [OFStdOut writeString: @"Parsing UnicodeData.txt…"]; while ((line = [response readLine]) != nil) { void *pool2; OFArray OF_GENERIC(OFString *) *components; OFUnichar codePoint; if (line.length == 0) continue; pool2 = objc_autoreleasePoolPush(); components = [line componentsSeparatedByString: @";"]; if (components.count != 15) { OFLog(@"Invalid line: %@\n", line); [OFApplication terminateWithStatus: 1]; } codePoint = (OFUnichar)[[components objectAtIndex: 0] unsignedLongLongValueWithBase: 16]; if (codePoint > 0x10FFFF) @throw [OFOutOfRangeException exception]; _uppercaseTable[codePoint] = (OFUnichar)[[components objectAtIndex: 12] unsignedLongLongValueWithBase: 16]; _lowercaseTable[codePoint] = (OFUnichar)[[components objectAtIndex: 13] unsignedLongLongValueWithBase: 16]; _titlecaseTable[codePoint] = (OFUnichar)[[components objectAtIndex: 14] unsignedLongLongValueWithBase: 16]; if ([[components objectAtIndex: 5] length] > 0) { OFArray *decomposed = [[components objectAtIndex: 5] componentsSeparatedByString: @" "]; bool compat = false; OFMutableString *string; if ([decomposed.firstObject hasPrefix: @"<"]) { decomposed = [decomposed objectsInRange: OFRangeMake(1, decomposed.count - 1)]; compat = true; } string = [OFMutableString string]; for (OFString *character in decomposed) { OFUnichar unichar = (OFUnichar)[character unsignedLongLongValueWithBase: 16]; [string appendCharacters: &unichar length: 1]; } [string makeImmutable]; if (!compat) _decompositionTable[codePoint] = [string copy]; _decompositionCompatTable[codePoint] = [string copy]; } objc_autoreleasePoolPop(pool2); } [self applyDecompositionRecursivelyForTable: _decompositionTable]; [self applyDecompositionRecursivelyForTable: _decompositionCompatTable]; [OFStdOut writeLine: @" done"]; [OFStdOut writeString: @"Downloading CaseFolding.txt…"]; _state = stateCaseFolding; request = [OFHTTPRequest requestWithURL: [OFURL URLWithString: caseFoldingURL]]; [_HTTPClient asyncPerformRequest: request]; } - (void)parseCaseFolding: (OFHTTPResponse *)response { OFString *line; [OFStdOut writeString: @"Parsing CaseFolding.txt…"]; while ((line = [response readLine]) != nil) { void *pool2; OFArray OF_GENERIC(OFString *) *components; OFUnichar codePoint; if (line.length == 0 || [line hasPrefix: @"#"]) continue; pool2 = objc_autoreleasePoolPush(); components = [line componentsSeparatedByString: @"; "]; if (components.count != 4) { OFLog(@"Invalid line: %s\n", line); [OFApplication terminateWithStatus: 1]; } if (![[components objectAtIndex: 1] isEqual: @"S"] && ![[components objectAtIndex: 1] isEqual: @"C"]) continue; codePoint = (OFUnichar)[[components objectAtIndex: 0] unsignedLongLongValueWithBase: 16]; if (codePoint > 0x10FFFF) @throw [OFOutOfRangeException exception]; _caseFoldingTable[codePoint] = (OFUnichar)[[components objectAtIndex: 2] unsignedLongLongValueWithBase: 16]; objc_autoreleasePoolPop(pool2); } [OFStdOut writeLine: @" done"]; [self writeFiles]; } - (void)applyDecompositionRecursivelyForTable: (OFString *[0x110000])table { bool done; do { done = true; for (OFUnichar i = 0; i < 0x110000; i++) { void *pool; const OFUnichar *characters; size_t length; OFMutableString *replacement; bool changed = false; if (table[i] == nil) continue; |
︙ | ︙ | |||
270 271 272 273 274 275 276 | } while (!done); } - (void)writeFiles { OFURL *URL; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | } while (!done); } - (void)writeFiles { OFURL *URL; [OFStdOut writeString: @"Writing files…"]; URL = [OFURL fileURLWithPath: @"../../src/unicode.m"]; [self writeTablesToFile: URL.fileSystemRepresentation]; URL = [OFURL fileURLWithPath: @"../../src/unicode.h"]; [self writeHeaderToFile: URL.fileSystemRepresentation]; [OFStdOut writeLine: @" done"]; [OFApplication terminate]; } - (void)writeTablesToFile: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFFile *file = [OFFile fileWithPath: path mode: @"w"]; [file writeString: COPYRIGHT @"#include \"config.h\"\n" @"\n" @"#import \"OFString.h\"\n\n" @"static const OFUnichar emptyPage[0x100] = { 0 };\n" @"static const char *emptyDecompositionPage[0x100] = { NULL };\n" @"\n"]; /* Write uppercasePage%u */ for (OFUnichar i = 0; i < 0x110000; i += 0x100) { bool isEmpty = true; for (OFUnichar j = i; j < i + 0x100; j++) { if (_uppercaseTable[j] != 0) { isEmpty = false; _uppercaseTableSize = i >> 8; _uppercaseTableUsed[_uppercaseTableSize] = 1; break; } } if (!isEmpty) { void *pool2 = objc_autoreleasePoolPush(); [file writeFormat: @"static const OFUnichar " @"uppercasePage%u[0x100] = {\n", i >> 8]; for (OFUnichar j = i; j < i + 0x100; j += 8) [file writeFormat: @"\t%u, %u, %u, %u, %u, %u, %u, %u,\n", _uppercaseTable[j], _uppercaseTable[j + 1], _uppercaseTable[j + 2], _uppercaseTable[j + 3], _uppercaseTable[j + 4], _uppercaseTable[j + 5], _uppercaseTable[j + 6], _uppercaseTable[j + 7]]; [file writeString: @"};\n\n"]; objc_autoreleasePoolPop(pool2); } } /* Write lowercasePage%u */ for (OFUnichar i = 0; i < 0x110000; i += 0x100) { bool isEmpty = true; for (OFUnichar j = i; j < i + 0x100; j++) { if (_lowercaseTable[j] != 0) { isEmpty = false; _lowercaseTableSize = i >> 8; _lowercaseTableUsed[_lowercaseTableSize] = 1; break; } } if (!isEmpty) { void *pool2 = objc_autoreleasePoolPush(); [file writeFormat: @"static const OFUnichar " @"lowercasePage%u[0x100] = {\n", i >> 8]; for (OFUnichar j = i; j < i + 0x100; j += 8) [file writeFormat: @"\t%u, %u, %u, %u, %u, %u, %u, %u,\n", _lowercaseTable[j], _lowercaseTable[j + 1], _lowercaseTable[j + 2], _lowercaseTable[j + 3], _lowercaseTable[j + 4], _lowercaseTable[j + 5], _lowercaseTable[j + 6], _lowercaseTable[j + 7]]; [file writeString: @"};\n\n"]; objc_autoreleasePoolPop(pool2); } } /* Write titlecasePage%u if it does NOT match uppercasePage%u */ for (OFUnichar i = 0; i < 0x110000; i += 0x100) { bool isEmpty = true; for (OFUnichar j = i; j < i + 0x100; j++) { if (_titlecaseTable[j] != 0) { isEmpty = !memcmp(_uppercaseTable + i, _titlecaseTable + i, 256 * sizeof(OFUnichar)); _titlecaseTableSize = i >> 8; _titlecaseTableUsed[_titlecaseTableSize] = (isEmpty ? 2 : 1); break; } } if (!isEmpty) { void *pool2 = objc_autoreleasePoolPush(); [file writeFormat: @"static const OFUnichar " @"titlecasePage%u[0x100] = {\n", i >> 8]; for (OFUnichar j = i; j < i + 0x100; j += 8) [file writeFormat: @"\t%u, %u, %u, %u, %u, %u, %u, %u,\n", _titlecaseTable[j], _titlecaseTable[j + 1], _titlecaseTable[j + 2], _titlecaseTable[j + 3], _titlecaseTable[j + 4], _titlecaseTable[j + 5], _titlecaseTable[j + 6], _titlecaseTable[j + 7]]; [file writeString: @"};\n\n"]; objc_autoreleasePoolPop(pool2); } } /* Write caseFoldingPage%u if it does NOT match lowercasePage%u */ for (OFUnichar i = 0; i < 0x110000; i += 0x100) { bool isEmpty = true; for (OFUnichar j = i; j < i + 0x100; j++) { if (_caseFoldingTable[j] != 0) { isEmpty = !memcmp(_lowercaseTable + i, _caseFoldingTable + i, 256 * sizeof(OFUnichar)); _caseFoldingTableSize = i >> 8; _caseFoldingTableUsed[_caseFoldingTableSize] = (isEmpty ? 2 : 1); break; } } if (!isEmpty) { void *pool2 = objc_autoreleasePoolPush(); [file writeFormat: @"static const OFUnichar " @"caseFoldingPage%u[0x100] = {\n", i >> 8]; for (OFUnichar j = i; j < i + 0x100; j += 8) [file writeFormat: @"\t%u, %u, %u, %u, %u, %u, %u, %u,\n", _caseFoldingTable[j], _caseFoldingTable[j + 1], _caseFoldingTable[j + 2], _caseFoldingTable[j + 3], _caseFoldingTable[j + 4], _caseFoldingTable[j + 5], _caseFoldingTable[j + 6], _caseFoldingTable[j + 7]]; [file writeString: @"};\n\n"]; objc_autoreleasePoolPop(pool2); } } /* Write decompositionPage%u */ for (OFUnichar i = 0; i < 0x110000; i += 0x100) { bool isEmpty = true; for (OFUnichar j = i; j < i + 0x100; j++) { if (_decompositionTable[j] != nil) { isEmpty = false; _decompositionTableSize = i >> 8; _decompositionTableUsed[ _decompositionTableSize] = 1; break; } } if (!isEmpty) { void *pool2 = objc_autoreleasePoolPush(); [file writeFormat: @"static const char *const " @"decompositionPage%u[0x100] = {\n", i >> 8]; for (OFUnichar j = i; j < i + 0x100; j++) { if ((j - i) % 2 == 0) [file writeString: @"\t"]; else [file writeString: @" "]; if (_decompositionTable[j] != nil) { const char *UTF8String = |
︙ | ︙ | |||
510 511 512 513 514 515 516 | [file writeString: @"};\n\n"]; objc_autoreleasePoolPop(pool2); } } /* Write decompCompatPage%u if it does NOT match decompositionPage%u */ | | | | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | [file writeString: @"};\n\n"]; objc_autoreleasePoolPop(pool2); } } /* Write decompCompatPage%u if it does NOT match decompositionPage%u */ for (OFUnichar i = 0; i < 0x110000; i += 0x100) { bool isEmpty = true; for (OFUnichar j = i; j < i + 0x100; j++) { if (_decompositionCompatTable[j] != 0) { /* * We bulk-compare pointers via memcmp here. * This is safe, as we always set the same * pointer in both tables if both are the same. */ isEmpty = !memcmp(_decompositionTable + i, |
︙ | ︙ | |||
539 540 541 542 543 544 545 | if (!isEmpty) { void *pool2 = objc_autoreleasePoolPush(); [file writeFormat: @"static const char *const " @"decompCompatPage%u[0x100] = {\n", i >> 8]; | | | 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 | if (!isEmpty) { void *pool2 = objc_autoreleasePoolPush(); [file writeFormat: @"static const char *const " @"decompCompatPage%u[0x100] = {\n", i >> 8]; for (OFUnichar j = i; j < i + 0x100; j++) { if ((j - i) % 2 == 0) [file writeString: @"\t"]; else [file writeString: @" "]; if (_decompositionCompatTable[j] != nil) { const char *UTF8String = |
︙ | ︙ | |||
581 582 583 584 585 586 587 | /* * Those are currently set to the last index. * But from now on, we need the size. */ _uppercaseTableSize++; _lowercaseTableSize++; _titlecaseTableSize++; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 | /* * Those are currently set to the last index. * But from now on, we need the size. */ _uppercaseTableSize++; _lowercaseTableSize++; _titlecaseTableSize++; _caseFoldingTableSize++; _decompositionTableSize++; _decompositionCompatTableSize++; /* Write OFUnicodeUppercaseTable */ [file writeFormat: @"const OFUnichar *const " @"OFUnicodeUppercaseTable[0x%X] = {\n\t", _uppercaseTableSize]; for (OFUnichar i = 0; i < _uppercaseTableSize; i++) { if (_uppercaseTableUsed[i]) [file writeFormat: @"uppercasePage%u", i]; else [file writeString: @"emptyPage"]; if (i + 1 < _uppercaseTableSize) { if ((i + 1) % 4 == 0) [file writeString: @",\n\t"]; else [file writeString: @", "]; } } [file writeString: @"\n};\n\n"]; /* Write OFUnicodeLowercaseTable */ [file writeFormat: @"const OFUnichar *const " @"OFUnicodeLowercaseTable[0x%X] = {\n\t", _lowercaseTableSize]; for (OFUnichar i = 0; i < _lowercaseTableSize; i++) { if (_lowercaseTableUsed[i]) [file writeFormat: @"lowercasePage%u", i]; else [file writeString: @"emptyPage"]; if (i + 1 < _lowercaseTableSize) { if ((i + 1) % 4 == 0) [file writeString: @",\n\t"]; else [file writeString: @", "]; } } [file writeString: @"\n};\n\n"]; /* Write OFUnicodeTitlecaseTable */ [file writeFormat: @"const OFUnichar *const " @"OFUnicodeTitlecaseTable[0x%X] = {\n\t", _titlecaseTableSize]; for (OFUnichar i = 0; i < _titlecaseTableSize; i++) { if (_titlecaseTableUsed[i] == 1) [file writeFormat: @"titlecasePage%u", i]; else if (_titlecaseTableUsed[i] == 2) [file writeFormat: @"uppercasePage%u", i]; else [file writeString: @"emptyPage"]; if (i + 1 < _titlecaseTableSize) { if ((i + 1) % 4 == 0) [file writeString: @",\n\t"]; else [file writeString: @", "]; } } [file writeString: @"\n};\n\n"]; /* Write OFUnicodeCaseFoldingTable */ [file writeFormat: @"const OFUnichar *const " @"OFUnicodeCaseFoldingTable[0x%X] = {\n\t", _caseFoldingTableSize]; for (OFUnichar i = 0; i < _caseFoldingTableSize; i++) { if (_caseFoldingTableUsed[i] == 1) [file writeFormat: @"caseFoldingPage%u", i]; else if (_caseFoldingTableUsed[i] == 2) [file writeFormat: @"lowercasePage%u", i]; else [file writeString: @"emptyPage"]; if (i + 1 < _caseFoldingTableSize) { if ((i + 1) % 3 == 0) [file writeString: @",\n\t"]; else [file writeString: @", "]; } } [file writeString: @"\n};\n\n"]; /* Write OFUnicodeDecompositionTable */ [file writeFormat: @"const char *const " @"*OFUnicodeDecompositionTable[0x%X] = {\n\t", _decompositionTableSize]; for (OFUnichar i = 0; i < _decompositionTableSize; i++) { if (_decompositionTableUsed[i]) [file writeFormat: @"decompositionPage%u", i]; else [file writeString: @"emptyDecompositionPage"]; if (i + 1 < _decompositionTableSize) { if ((i + 1) % 3 == 0) [file writeString: @",\n\t"]; else [file writeString: @", "]; } } [file writeString: @"\n};\n\n"]; /* Write OFUnicodeDecompositionCompatTable */ [file writeFormat: @"const char *const " @"*OFUnicodeDecompositionCompatTable[0x%X] = {" @"\n\t", _decompositionCompatTableSize]; for (OFUnichar i = 0; i < _decompositionCompatTableSize; i++) { if (_decompositionCompatTableUsed[i] == 1) [file writeFormat: @"decompCompatPage%u", i]; else if (_decompositionCompatTableUsed[i] == 2) [file writeFormat: @"decompositionPage%u", i]; else [file writeString: @"emptyDecompositionPage"]; |
︙ | ︙ | |||
731 732 733 734 735 736 737 | OFFile *file = [OFFile fileWithPath: path mode: @"w"]; [file writeString: COPYRIGHT @"#import \"OFString.h\"\n\n"]; [file writeFormat: | | | | | | | | | | < | | < | | < | | < | | | < > | 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 | OFFile *file = [OFFile fileWithPath: path mode: @"w"]; [file writeString: COPYRIGHT @"#import \"OFString.h\"\n\n"]; [file writeFormat: @"#define OFUnicodeUppercaseTableSize 0x%X\n" @"#define OFUnicodeLowercaseTableSize 0x%X\n" @"#define OFUnicodeTitlecaseTableSize 0x%X\n" @"#define OFUnicodeCaseFoldingTableSize 0x%X\n" @"#define OFUnicodeDecompositionTableSize 0x%X\n" @"#define OFUnicodeDecompositionCompatTableSize 0x%X\n\n", _uppercaseTableSize, _lowercaseTableSize, _titlecaseTableSize, _caseFoldingTableSize, _decompositionTableSize, _decompositionCompatTableSize]; [file writeString: @"#ifdef __cplusplus\n" @"extern \"C\" {\n" @"#endif\n" @"extern const OFUnichar *const _Nonnull\n" @" OFUnicodeUppercaseTable[OFUnicodeUppercaseTableSize];\n" @"extern const OFUnichar *const _Nonnull\n" @" OFUnicodeLowercaseTable[OFUnicodeLowercaseTableSize];\n" @"extern const OFUnichar *const _Nonnull\n" @" OFUnicodeTitlecaseTable[OFUnicodeTitlecaseTableSize];\n" @"extern const OFUnichar *const _Nonnull\n" @" OFUnicodeCaseFoldingTable[OFUnicodeCaseFoldingTableSize];\n" @"extern const char *const _Nullable *const _Nonnull\n" @" OFUnicodeDecompositionTable[" @"OFUnicodeDecompositionTableSize];\n" @"extern const char *const _Nullable *const _Nonnull\n" @" OFUnicodeDecompositionCompatTable[" @"OFUnicodeDecompositionCompatTableSize];\n" @"#ifdef __cplusplus\n" @"}\n" @"#endif\n"]; objc_autoreleasePoolPop(pool); } @end |
Renamed and modified generators/copyright.h [5f052aece5] to generators/unicode/copyright.h [c0b22b50fd].
1 | /* | < < | < < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFString.h" #define COPYRIGHT \ @"/*\n" \ @" * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im>\n" \ @" *\n" \ @" * All rights reserved.\n" \ @" *\n" \ @" * This file is part of ObjFW. It may be distributed under the terms " \ @"of the\n" \ @" * Q Public License 1.0, which can be found in the file LICENSE.QPL " \ @"included in\n" \ |
︙ | ︙ |
Added objfw.spec version [01416894bd].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | %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} Summary: Portable, lightweight framework for the Objective-C language %if 0%{?suse_version} License: QPL-1.0 or GPL-3.0 or GPL-2.0 Group: Development/Languages/C and C++ %else License: QPL or GPLv3 or GPLv2 %endif URL: https://objfw.nil.im Source0: objfw-%{version}.tar.gz 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} Requires: ofdns%{_isa} = %{version}-%{release} Requires: ofhash%{_isa} = %{version}-%{release} Requires: ofhttp%{_isa} = %{version}-%{release} %description ObjFW is a portable, lightweight framework for the Objective-C language. It enables you to write an application in Objective-C that will run on any platform supported by ObjFW without having to worry about differences between operating systems or various frameworks you would otherwise need if you want to be portable. It supports all modern Objective-C features when using Clang, but is also compatible with GCC ≥ 4.6 to allow maximum portability. ObjFW also comes with its own lightweight and extremely fast Objective-C runtime, which in real world use cases was found to be significantly faster than both GNU's and Apple's runtime. %package -n %{libobjfw_pkgname} Summary: ObjFW library Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release} %description -n %{libobjfw_pkgname} The %{libobjfw_pkgname} package contains the library needed by programs using ObjFW. %package -n %{libobjfw_pkgname}-devel 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, 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 and libraries for %{libobjfwrt_pkgname} Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release} %description -n %{libobjfwrt_pkgname}-devel The %{libobjfwrt_pkgname}-devel package contains header files and libraries for ObjFW's Objective-C runtime library. %package -n %{libobjfwtls_pkgname} Summary: TLS support for ObjFW Requires: 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} %description -n ofarc ofarc is a multi-format archive utility that allows creating, listing, extracting and modifying ZIP, Tar and LHA archives using ObjFW's classes for various archive types. %package -n ofdns Summary: Utility for performing DNS requests on the command line Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release} Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release} %description -n ofdns ofdns is an utility for performing DNS requests on the command line using ObjFW's DNS resolver. %package -n ofhash Summary: Utility to hash files with various cryptographic hash functions Requires: %{libobjfw_pkgname}%{_isa} = %{version}-%{release} Requires: %{libobjfwrt_pkgname}%{_isa} = %{version}-%{release} %description -n ofhash ofhash is an utility to hash files with various cryptographic hash functions (even using different algorithms at once) using ObjFW's classes for various cryptographic hashes. %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 proxy, a modern terminal-based UI, etc. %prep %autosetup ./autogen.sh %build %configure OBJC=clang --disable-rpath %make_build %install %make_install %check make -C tests run %if 0%{?suse_version} %post -n %{libobjfw_pkgname} -p /sbin/ldconfig %postun -n %{libobjfw_pkgname} -p /sbin/ldconfig %post -n %{libobjfwrt_pkgname} -p /sbin/ldconfig %postun -n %{libobjfwrt_pkgname} -p /sbin/ldconfig %endif %files %license LICENSE.QPL %license LICENSE.GPLv3 %license LICENSE.GPLv2 %files -n %{libobjfw_pkgname} %{_libdir}/libobjfw.so.%{libobjfw_major} %{_libdir}/libobjfw.so.%{libobjfw_major}.%{libobjfw_minor}.0 %license LICENSE.QPL %license LICENSE.GPLv3 %license LICENSE.GPLv2 %files -n %{libobjfw_pkgname}-devel %{_libdir}/libobjfw.so %dir %{_includedir}/ObjFW %{_includedir}/ObjFW %{_bindir}/objfw-compile %{_bindir}/objfw-config %{_bindir}/objfw-new %license LICENSE.QPL %license LICENSE.GPLv3 %license LICENSE.GPLv2 %files -n %{libobjfwrt_pkgname} %{_libdir}/libobjfwrt.so.%{libobjfwrt_major} %{_libdir}/libobjfwrt.so.%{libobjfwrt_major}.%{libobjfwrt_minor}.0 %license LICENSE.QPL %license LICENSE.GPLv3 %license LICENSE.GPLv2 %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 %{_datadir}/ofarc/lang/de.json %{_datadir}/ofarc/lang/languages.json %license LICENSE.QPL %license LICENSE.GPLv3 %license LICENSE.GPLv2 %files -n ofdns %{_bindir}/ofdns %{_datadir}/ofdns/lang/de.json %{_datadir}/ofdns/lang/languages.json %license LICENSE.QPL %license LICENSE.GPLv3 %license LICENSE.GPLv2 %files -n ofhash %{_bindir}/ofhash %{_datadir}/ofhash/lang/de.json %{_datadir}/ofhash/lang/languages.json %license LICENSE.QPL %license LICENSE.GPLv3 %license LICENSE.GPLv2 %files -n ofhttp %{_bindir}/ofhttp %{_datadir}/ofhttp/lang/de.json %{_datadir}/ofhttp/lang/languages.json %license LICENSE.QPL %license LICENSE.GPLv3 %license LICENSE.GPLv2 |
Modified src/Makefile from [da1634a438] to [6b94befb31].
1 2 | include ../extra.mk | | | < < < < < < < < < < < | < | < > > > > > < < < < < > > > > > | > > | < < < < < < < < < < < < < < > > < | > > > > > < < | | | > | | | < | | | | < | < < < > | > > > | > > | > | > > < | < < < < > > | < < < < > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | include ../extra.mk SUBDIRS = ${RUNTIME} exceptions encodings forwarding SUBDIRS_AFTER = ${BRIDGE} ${TLS} DISTCLEAN = Info.plist objfw-defs.h SHARED_LIB = ${OBJFW_SHARED_LIB} STATIC_LIB = ${OBJFW_STATIC_LIB} FRAMEWORK = ${OBJFW_FRAMEWORK} LIB_MAJOR = ${OBJFW_LIB_MAJOR} LIB_MINOR = ${OBJFW_LIB_MINOR} SRCS = OFApplication.m \ OFArray.m \ OFBlock.m \ OFCharacterSet.m \ OFColor.m \ OFConstantString.m \ OFCountedSet.m \ OFData.m \ OFData+CryptographicHashing.m \ OFData+MessagePackParsing.m \ OFDate.m \ OFDictionary.m \ OFEnumerator.m \ OFFileManager.m \ OFGZIPStream.m \ OFHMAC.m \ OFInflate64Stream.m \ OFInflateStream.m \ OFInvocation.m \ OFLHAArchive.m \ OFLHAArchiveEntry.m \ OFList.m \ OFLocale.m \ OFMD5Hash.m \ OFMapTable.m \ OFMessagePackExtension.m \ OFMethodSignature.m \ OFMutableArray.m \ OFMutableData.m \ OFMutableDictionary.m \ OFMutableLHAArchiveEntry.m \ OFMutablePair.m \ OFMutableSet.m \ 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 \ OFOnce.m \ OFOptionsParser.m \ OFPBKDF2.m \ OFPair.m \ OFRIPEMD160Hash.m \ OFRunLoop.m \ OFSHA1Hash.m \ OFSHA224Hash.m \ OFSHA224Or256Hash.m \ OFSHA256Hash.m \ OFSHA384Hash.m \ OFSHA384Or512Hash.m \ OFSHA512Hash.m \ OFScrypt.m \ OFSecureData.m \ OFSeekableStream.m \ OFSerialization.m \ OFSet.m \ OFSortedList.m \ OFStdIOStream.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_SUBPROCESS_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 \ OFXMLElement.m \ OFXMLElement+Serialization.m \ OFXMLElementBuilder.m \ OFXMLNode.m \ OFXMLParser.m \ OFXMLProcessingInstruction.m \ OFZIPArchive.m \ OFZIPArchiveEntry.m \ ${USE_SRCS_FILES} \ ${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_PLUGINS = OFPlugin.m SRCS_SOCKETS = OFDNSQuery.m \ OFDNSResolver.m \ OFDNSResourceRecord.m \ OFDNSResponse.m \ OFDatagramSocket.m \ OFHTTPClient.m \ OFHTTPCookie.m \ OFHTTPCookieManager.m \ OFHTTPRequest.m \ OFHTTPResponse.m \ OFHTTPServer.m \ OFSequencedPacketSocket.m \ OFSocket.m \ OFStreamSocket.m \ OFTCPSocket.m \ OFTLSStream.m \ OFUDPSocket.m \ ${USE_SRCS_IPX} \ ${USE_SRCS_UNIX_SOCKETS} SRCS_IPX = OFIPXSocket.m \ OFSPXSocket.m \ OFSPXStreamSocket.m SRCS_UNIX_SOCKETS = OFUNIXDatagramSocket.m \ OFUNIXStreamSocket.m SRCS_THREADS = OFCondition.m \ OFMutex.m \ OFPlainCondition.m \ OFPlainMutex.m \ OFPlainThread.m \ OFRecursiveMutex.m \ OFTLSKey.m SRCS_WINDOWS = OFWin32ConsoleStdIOStream.m \ OFWindowsRegistryKey.m INCLUDES_ATOMIC = OFAtomic.h \ platform/GCC4/OFAtomic.h \ platform/GCC4.7/OFAtomic.h \ platform/PowerPC/OFAtomic.h \ platform/macOS/OFAtomic.h \ platform/x86/OFAtomic.h INCLUDES := ${SRCS:.m=.h} \ OFCollection.h \ OFCryptographicHash.h \ OFJSONRepresentation.h \ OFKernelEventObserver.h \ OFKeyValueCoding.h \ OFLocking.h \ OFMessagePackRepresentation.h \ ObjFW.h \ macros.h \ objfw-defs.h \ platform.h \ ${USE_INCLUDES_ATOMIC} 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 \ OFMutableMapTableDictionary.m \ OFMutableMapTableSet.m \ OFMutableUTF8String.m \ OFNonretainedObjectValue.m \ OFPointValue.m \ OFPointerValue.m \ 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_SOCKETS += OFDNSResolverSettings.m \ ${OF_EPOLL_KERNEL_EVENT_OBSERVER_M} \ OFHTTPURLHandler.m \ OFHostAddressResolver.m \ OFIPSocketAsyncConnector.m \ OFKernelEventObserver.m \ ${OF_KQUEUE_KERNEL_EVENT_OBSERVER_M} \ ${OF_POLL_KERNEL_EVENT_OBSERVER_M} \ ${OF_SELECT_KERNEL_EVENT_OBSERVER_M} \ OFTCPSocketSOCKS5Connector.m OBJS_EXTRA = exceptions/exceptions.a \ encodings/encodings.a \ forwarding/forwarding.a LIB_OBJS_EXTRA = exceptions/exceptions.lib.a \ encodings/encodings.lib.a \ forwarding/forwarding.lib.a include ../buildsys.mk CPPFLAGS += -I. -I.. -Iexceptions -Iruntime LD = ${OBJC} FRAMEWORK_LIBS := -Fruntime \ ${RUNTIME_FRAMEWORK_LIBS} \ ${REEXPORT_RUNTIME_FRAMEWORK} \ ${LIBS} LIBS := -Lruntime ${RUNTIME_LIBS} ${REEXPORT_RUNTIME} ${LIBS} |
Deleted src/OFASN1BitString.h version [dd9e3e424b].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1BitString.m version [58adebf4a8].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1Boolean.h version [f9c4678a9e].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1Boolean.m version [ab43e337d1].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1DERRepresentation.h version [878337daf1].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1Enumerated.h version [5baa4a294f].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1Enumerated.m version [ba2cabe5ff].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1IA5String.h version [c414c3313c].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1IA5String.m version [6816147795].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1Integer.h version [a73f7cf242].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1Integer.m version [e6486b0fce].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1NumericString.h version [3a5c85e7cd].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1NumericString.m version [1f3277f085].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1ObjectIdentifier.h version [4f0a319e02].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1ObjectIdentifier.m version [0496bf5735].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1OctetString.h version [6d83ed8333].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1OctetString.m version [3d5ad35b08].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1PrintableString.h version [302daaf706].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1PrintableString.m version [d326d7d84e].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1UTF8String.h version [8f256e2e35].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1UTF8String.m version [fe525c2cd3].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1Value.h version [80070a2f85].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFASN1Value.m version [e6d6355cac].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Renamed and modified src/of_asprintf.h [5347c6d019] to src/OFASPrintF.h [090f42d33a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | #import "macros.h" OF_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { #endif | | < < | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #import "macros.h" OF_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { #endif extern int OFVASPrintF( char *_Nullable *_Nonnull, const char *_Nonnull, va_list); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Renamed and modified src/of_asprintf.m [cd42320784] to src/OFASPrintF.m [31044637f2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
39 40 41 42 43 44 45 | #endif #import "OFString.h" #import "OFLocale.h" #import "OFInitializationFailedException.h" | | | | | | | | | | | | | | | | | | | | | < | | < < < < | | | | > > | > | < | | > > | < < < | | > | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | #endif #import "OFString.h" #import "OFLocale.h" #import "OFInitializationFailedException.h" #define maxSubformatLen 64 #ifndef HAVE_ASPRINTF /* * (v)asprintf might be declared, but HAVE_ASPRINTF not defined because * configure determined it is broken. In this case, we must make sure there is * no name clash. */ # define asprintf asprintf_ # define vasprintf vasprintf_ #endif struct Context { const char *format; size_t formatLen; char subformat[maxSubformatLen + 1]; size_t subformatLen; va_list arguments; char *buffer; size_t bufferLen; size_t i, last; enum { stateString, stateFormatFlags, stateFormatFieldWidth, stateFormatLengthModifier, stateFormatConversionSpecifier } state; enum { lengthModifierNone, lengthModifierHH, lengthModifierH, lengthModifierL, lengthModifierLL, lengthModifierJ, lengthModifierZ, lengthModifierT, lengthModifierCapitalL } lengthModifier; bool useLocale; }; #ifdef HAVE_ASPRINTF_L static locale_t cLocale; OF_CONSTRUCTOR() { if ((cLocale = newlocale(LC_ALL_MASK, "C", NULL)) == NULL) @throw [OFInitializationFailedException exception]; } #endif #ifndef HAVE_ASPRINTF static int vasprintf(char **string, const char *format, va_list arguments) { int length; size_t bufferLength = 128; *string = NULL; for (;;) { free(*string); if ((*string = malloc(bufferLength)) == NULL) return -1; length = vsnprintf(*string, bufferLength - 1, format, arguments); if (length >= 0 && (size_t)length < bufferLength - 1) break; if (bufferLength > INT_MAX / 2) { free(*string); return -1; } bufferLength <<= 1; } if (length > 0 && (size_t)length != bufferLength - 1) { char *resized = realloc(*string, length + 1); /* Ignore if making it smaller failed. */ if (resized != NULL) *string = resized; } return length; } static int |
︙ | ︙ | |||
149 150 151 152 153 154 155 | va_end(arguments); return ret; } #endif static bool | | | | | | | | | | | | | | | | | | | | | | | | | | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | va_end(arguments); return ret; } #endif static bool appendString(struct Context *ctx, const char *append, size_t appendLen) { char *newBuf; if (appendLen == 0) return true; if ((newBuf = realloc(ctx->buffer, ctx->bufferLen + appendLen + 1)) == NULL) return false; memcpy(newBuf + ctx->bufferLen, append, appendLen); ctx->buffer = newBuf; ctx->bufferLen += appendLen; return true; } static bool appendSubformat(struct Context *ctx, const char *subformat, size_t subformatLen) { if (ctx->subformatLen + subformatLen > maxSubformatLen) return false; memcpy(ctx->subformat + ctx->subformatLen, subformat, subformatLen); ctx->subformatLen += subformatLen; ctx->subformat[ctx->subformatLen] = 0; return true; } static bool stringState(struct Context *ctx) { if (ctx->format[ctx->i] == '%') { if (ctx->i > 0) if (!appendString(ctx, ctx->format + ctx->last, ctx->i - ctx->last)) return false; if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; ctx->last = ctx->i + 1; ctx->state = stateFormatFlags; } return true; } static bool formatFlagsState(struct Context *ctx) { switch (ctx->format[ctx->i]) { case '-': case '+': case ' ': case '#': case '0': if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; break; case ',': /* ObjFW extension: Use decimal point from locale */ ctx->useLocale = true; break; default: ctx->state = stateFormatFieldWidth; ctx->i--; break; } return true; } static bool formatFieldWidthState(struct Context *ctx) { if ((ctx->format[ctx->i] >= '0' && ctx->format[ctx->i] <= '9') || ctx->format[ctx->i] == '*' || ctx->format[ctx->i] == '.') { if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; } else { ctx->state = stateFormatLengthModifier; ctx->i--; } return true; } static bool formatLengthModifierState(struct Context *ctx) { /* Only one allowed */ switch (ctx->format[ctx->i]) { case 'h': /* and also hh */ if (ctx->formatLen > ctx->i + 1 && ctx->format[ctx->i + 1] == 'h') { if (!appendSubformat(ctx, ctx->format + ctx->i, 2)) return false; ctx->i++; ctx->lengthModifier = lengthModifierHH; } else { if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; ctx->lengthModifier = lengthModifierH; } break; case 'l': /* and also ll */ if (ctx->formatLen > ctx->i + 1 && ctx->format[ctx->i + 1] == 'l') { #ifndef OF_WINDOWS if (!appendSubformat(ctx, ctx->format + ctx->i, 2)) return false; #else if (!appendSubformat(ctx, "I64", 3)) return false; #endif ctx->i++; ctx->lengthModifier = lengthModifierLL; } else { if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; ctx->lengthModifier = lengthModifierL; } break; case 'j': #if defined(OF_WINDOWS) if (!appendSubformat(ctx, "I64", 3)) return false; #elif defined(_NEWLIB_VERSION) || defined(OF_HPUX) if (!appendSubformat(ctx, "ll", 2)) return false; #else if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; #endif ctx->lengthModifier = lengthModifierJ; break; case 'z': #if defined(OF_WINDOWS) if (sizeof(size_t) == 8) if (!appendSubformat(ctx, "I64", 3)) return false; #elif defined(_NEWLIB_VERSION) || defined(OF_HPUX) if (!appendSubformat(ctx, "l", 1)) return false; #else if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; #endif ctx->lengthModifier = lengthModifierZ; break; case 't': #if defined(OF_WINDOWS) if (sizeof(ptrdiff_t) == 8) if (!appendSubformat(ctx, "I64", 3)) return false; #elif defined(_NEWLIB_VERSION) || defined(OF_HPUX) if (!appendSubformat(ctx, "l", 1)) return false; #else if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; #endif ctx->lengthModifier = lengthModifierT; break; case 'L': if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; ctx->lengthModifier = lengthModifierCapitalL; break; #ifdef OF_WINDOWS case 'I': /* win32 strangeness (I64 instead of ll or j) */ if (ctx->formatLen > ctx->i + 2 && ctx->format[ctx->i + 1] == '6' && ctx->format[ctx->i + 2] == '4') { if (!appendSubformat(ctx, ctx->format + ctx->i, 3)) return false; ctx->i += 2; ctx->lengthModifier = lengthModifierLL; } else ctx->i--; break; #endif #ifdef OF_IOS case 'q': /* iOS uses this for PRI?64 */ if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; ctx->lengthModifier = lengthModifierLL; break; #endif default: ctx->i--; break; } ctx->state = stateFormatConversionSpecifier; return true; } static bool formatConversionSpecifierState(struct Context *ctx) { char *tmp = NULL; int tmpLen = 0; #ifndef HAVE_ASPRINTF_L OFString *point; #endif if (!appendSubformat(ctx, ctx->format + ctx->i, 1)) return false; switch (ctx->format[ctx->i]) { case '@': if (ctx->lengthModifier != lengthModifierNone) return false; ctx->subformat[ctx->subformatLen - 1] = 's'; @try { id object; |
︙ | ︙ | |||
412 413 414 415 416 417 418 | } @catch (id e) { free(ctx->buffer); @throw e; } break; case 'C': | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 | } @catch (id e) { free(ctx->buffer); @throw e; } break; case 'C': if (ctx->lengthModifier != lengthModifierNone) return false; ctx->subformat[ctx->subformatLen - 1] = 's'; { char buffer[5]; size_t len = OFUTF8StringEncode( va_arg(ctx->arguments, OFUnichar), buffer); if (len == 0) return false; buffer[len] = 0; tmpLen = asprintf(&tmp, ctx->subformat, buffer); } break; case 'S': if (ctx->lengthModifier != lengthModifierNone) return false; ctx->subformat[ctx->subformatLen - 1] = 's'; { const OFUnichar *arg = va_arg(ctx->arguments, const OFUnichar *); size_t j, len = OFUTF32StringLength(arg); char *buffer; if (SIZE_MAX / 4 < len || (SIZE_MAX / 4) - len < 1) return false; if ((buffer = malloc((len * 4) + 1)) == NULL) return false; j = 0; for (size_t i = 0; i < len; i++) { size_t clen = OFUTF8StringEncode(arg[i], buffer + j); if (clen == 0) { free(buffer); return false; } j += clen; } buffer[j] = 0; tmpLen = asprintf(&tmp, ctx->subformat, buffer); free(buffer); } break; case 'd': case 'i': switch (ctx->lengthModifier) { case lengthModifierNone: case lengthModifierHH: case lengthModifierH: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, int)); break; case lengthModifierL: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, long)); break; case lengthModifierLL: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, long long)); break; case lengthModifierJ: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, intmax_t)); break; case lengthModifierZ: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, ssize_t)); break; case lengthModifierT: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, ptrdiff_t)); break; default: return false; } break; case 'o': case 'u': case 'x': case 'X': switch (ctx->lengthModifier) { case lengthModifierNone: case lengthModifierHH: case lengthModifierH: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, unsigned int)); break; case lengthModifierL: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, unsigned long)); break; case lengthModifierLL: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, unsigned long long)); break; case lengthModifierJ: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, uintmax_t)); break; case lengthModifierZ: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, size_t)); break; case lengthModifierT: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, ptrdiff_t)); break; default: return false; } break; case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': case 'a': case 'A': switch (ctx->lengthModifier) { case lengthModifierNone: case lengthModifierL: #ifdef HAVE_ASPRINTF_L if (!ctx->useLocale) tmpLen = asprintf_l(&tmp, cLocale, ctx->subformat, va_arg(ctx->arguments, double)); else #endif tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, double)); break; case lengthModifierCapitalL: #ifdef HAVE_ASPRINTF_L if (!ctx->useLocale) tmpLen = asprintf_l(&tmp, cLocale, ctx->subformat, va_arg(ctx->arguments, long double)); else #endif |
︙ | ︙ | |||
614 615 616 617 618 619 620 | tmp = tmp2; } #endif break; case 'c': switch (ctx->lengthModifier) { | | | | | | | | | | | | | | | | 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 | tmp = tmp2; } #endif break; case 'c': switch (ctx->lengthModifier) { case lengthModifierNone: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, int)); break; case lengthModifierL: #ifdef HAVE_WCHAR_H # if WINT_MAX >= INT_MAX tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, wint_t)); # else tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, int)); # endif break; #endif default: return false; } break; case 's': switch (ctx->lengthModifier) { case lengthModifierNone: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, const char *)); break; #ifdef HAVE_WCHAR_T case lengthModifierL: tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, const wchar_t *)); break; #endif default: return false; } break; case 'p': if (ctx->lengthModifier != lengthModifierNone) return false; tmpLen = asprintf(&tmp, ctx->subformat, va_arg(ctx->arguments, void *)); break; case 'n': switch (ctx->lengthModifier) { case lengthModifierNone: *va_arg(ctx->arguments, int *) = (int)ctx->bufferLen; break; case lengthModifierHH: *va_arg(ctx->arguments, signed char *) = (signed char)ctx->bufferLen; break; case lengthModifierH: *va_arg(ctx->arguments, short *) = (short)ctx->bufferLen; break; case lengthModifierL: *va_arg(ctx->arguments, long *) = (long)ctx->bufferLen; break; case lengthModifierLL: *va_arg(ctx->arguments, long long *) = (long long)ctx->bufferLen; break; case lengthModifierJ: *va_arg(ctx->arguments, intmax_t *) = (intmax_t)ctx->bufferLen; break; case lengthModifierZ: *va_arg(ctx->arguments, size_t *) = (size_t)ctx->bufferLen; break; case lengthModifierT: *va_arg(ctx->arguments, ptrdiff_t *) = (ptrdiff_t)ctx->bufferLen; break; default: return false; } break; case '%': if (ctx->lengthModifier != lengthModifierNone) return false; if (!appendString(ctx, "%", 1)) return false; break; default: |
︙ | ︙ | |||
721 722 723 724 725 726 727 | free(tmp); return false; } free(tmp); } | | | | | | | | | | | < < < < < < < < < < < < < | 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 | free(tmp); return false; } free(tmp); } memset(ctx->subformat, 0, maxSubformatLen); ctx->subformatLen = 0; ctx->lengthModifier = lengthModifierNone; ctx->useLocale = false; ctx->last = ctx->i + 1; ctx->state = stateString; return true; } static bool (*states[])(struct Context *) = { stringState, formatFlagsState, formatFieldWidthState, formatLengthModifierState, formatConversionSpecifierState }; int OFVASPrintF(char **string, const char *format, va_list arguments) { struct Context ctx; ctx.format = format; ctx.formatLen = strlen(format); memset(ctx.subformat, 0, maxSubformatLen + 1); ctx.subformatLen = 0; va_copy(ctx.arguments, arguments); ctx.bufferLen = 0; ctx.last = 0; ctx.state = stateString; ctx.lengthModifier = lengthModifierNone; ctx.useLocale = false; if ((ctx.buffer = malloc(1)) == NULL) return -1; for (ctx.i = 0; ctx.i < ctx.formatLen; ctx.i++) { if (!states[ctx.state](&ctx)) { free(ctx.buffer); return -1; } } if (ctx.state != stateString) { free(ctx.buffer); return -1; } if (!appendString(&ctx, ctx.format + ctx.last, ctx.formatLen - ctx.last)) { free(ctx.buffer); return -1; } ctx.buffer[ctx.bufferLen] = 0; *string = ctx.buffer; return (ctx.bufferLen <= INT_MAX ? (int)ctx.bufferLen : -1); } |
Modified src/OFAdjacentArray.h from [4bd8d9c907] to [9facc27db0].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFAdjacentArray.m from [b6ccf04769] to [e305e33733].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
59 60 61 62 63 64 65 | [self release]; @throw e; } return self; } | | < | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | [self release]; @throw e; } return self; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { self = [self init]; @try { id object; [_array addItem: &firstObject]; |
︙ | ︙ | |||
107 108 109 110 111 112 113 | @throw e; } @try { for (size_t i = 0; i < count; i++) [objects[i] retain]; | | < | < | < | | | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | @throw e; } @try { for (size_t i = 0; i < count; i++) [objects[i] retain]; [_array addItems: objects count: count]; } @catch (id e) { for (size_t i = 0; i < count; i++) [objects[i] release]; /* Prevent double-release of objects */ [_array release]; _array = nil; [self release]; @throw e; } return self; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { self = [self init]; @try { bool ok = true; for (size_t i = 0; i < count; i++) { if (objects[i] == nil) ok = false; [objects[i] retain]; } if (!ok) @throw [OFInvalidArgumentException exception]; [_array addItems: objects count: count]; } @catch (id e) { for (size_t i = 0; i < count; i++) [objects[i] release]; [self release]; @throw e; } return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if ((![element.name isEqual: @"OFArray"] && ![element.name isEqual: @"OFMutableArray"]) || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; for (OFXMLElement *child in [element elementsForNamespace: OFSerializationNS]) { void *pool2 = objc_autoreleasePoolPush(); id object; object = child.objectByDeserializing; [_array addItem: &object]; [object retain]; |
︙ | ︙ | |||
208 209 210 211 212 213 214 | } - (id)objectAtIndexedSubscript: (size_t)idx { return *((id *)[_array itemAtIndex: idx]); } | | < | | | | | | < | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | } - (id)objectAtIndexedSubscript: (size_t)idx { return *((id *)[_array itemAtIndex: idx]); } - (void)getObjects: (id *)buffer inRange: (OFRange)range { id const *objects = _array.items; size_t count = _array.count; if (range.length > SIZE_MAX - range.location || range.location + range.length > count) @throw [OFOutOfRangeException exception]; for (size_t i = 0; i < range.length; i++) buffer[i] = objects[range.location + i]; } - (size_t)indexOfObject: (id)object { id const *objects; size_t count; if (object == nil) return OFNotFound; objects = _array.items; count = _array.count; for (size_t i = 0; i < count; i++) if ([objects[i] isEqual: object]) return i; return OFNotFound; } - (size_t)indexOfObjectIdenticalTo: (id)object { id const *objects; size_t count; if (object == nil) return OFNotFound; objects = _array.items; count = _array.count; for (size_t i = 0; i < count; i++) if (objects[i] == object) return i; return OFNotFound; } - (OFArray *)objectsInRange: (OFRange)range { if (range.length > SIZE_MAX - range.location || range.location + range.length > _array.count) @throw [OFOutOfRangeException exception]; if ([self isKindOfClass: [OFMutableArray class]]) return [OFArray arrayWithObjects: (id *)_array.items + range.location count: range.length]; return [OFAdjacentSubarray arrayWithArray: self range: range]; } - (bool)isEqual: (id)object { OFArray *otherArray; id const *objects, *otherObjects; size_t count; |
︙ | ︙ | |||
308 309 310 311 312 313 314 | return true; } - (unsigned long)hash { id const *objects = _array.items; size_t count = _array.count; | | | | | | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | return true; } - (unsigned long)hash { id const *objects = _array.items; size_t count = _array.count; unsigned long hash; OFHashInit(&hash); for (size_t i = 0; i < count; i++) OFHashAddHash(&hash, [objects[i] hash]); OFHashFinalize(&hash); return hash; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count_ { size_t count = _array.count; if (count > INT_MAX) /* |
︙ | ︙ | |||
346 347 348 349 350 351 352 | state->itemsPtr = (id *)_array.items; state->mutationsPtr = (unsigned long *)self; return (int)count; } #ifdef OF_HAVE_BLOCKS | | | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | state->itemsPtr = (id *)_array.items; state->mutationsPtr = (unsigned long *)self; return (int)count; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (OFArrayEnumerationBlock)block { id const *objects = _array.items; size_t count = _array.count; bool stop = false; for (size_t i = 0; i < count && !stop; i++) block(objects[i], i, &stop); |
︙ | ︙ |
Modified src/OFAdjacentSubarray.h from [577fbbfc6a] to [08f4f942e1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFAdjacentSubarray.m from [dfdd4736b7] to [76d5c349a9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
51 52 53 54 55 56 57 | if (![objects[i] isEqual: otherObjects[i]]) return false; return true; } #ifdef OF_HAVE_BLOCKS | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | if (![objects[i] isEqual: otherObjects[i]]) return false; return true; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (OFArrayEnumerationBlock)block { id const *objects = self.objects; bool stop = false; for (size_t i = 0; i < _range.length && !stop; i++) block(objects[i], i, &stop); } #endif @end |
Modified src/OFApplication.h from [a2a9803d24] to [d7b817478b].
1 | /* | < < | > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include <signal.h> #import "OFObject.h" #import "OFNotification.h" OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFArray OF_GENERIC(ObjectType); @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFSandbox; @class OFString; /** * @brief 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. * * For example, it can be used like this: |
︙ | ︙ | |||
50 51 52 53 54 55 56 | * - (void)applicationDidFinishLaunching * { * [OFApplication terminate]; * } * @end * @endcode */ | | | | | | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | * - (void)applicationDidFinishLaunching * { * [OFApplication terminate]; * } * @end * @endcode */ #define OF_APPLICATION_DELEGATE(class_) \ int \ main(int argc, char *argv[]) \ { \ return OFApplicationMain(&argc, &argv, \ (class_ *)[[class_ alloc] init]); \ } #ifdef OF_HAVE_PLEDGE # define OF_HAVE_SANDBOX #endif /** |
︙ | ︙ | |||
143 144 145 146 147 148 149 150 151 152 153 154 155 156 | * @class OFApplication OFApplication.h ObjFW/OFApplication.h * * @brief A class which represents the application as an object. * * In order to create a new OFApplication, you should create a class conforming * to the optional @ref OFApplicationDelegate protocol and put * `OF_APPLICATION_DELEGATE(NameOfYourClass)` in the .m file of that class. */ OF_SUBCLASSING_RESTRICTED @interface OFApplication: OFObject { OFString *_programName; OFArray OF_GENERIC(OFString *) *_arguments; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_environment; | > > > > | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | * @class OFApplication OFApplication.h ObjFW/OFApplication.h * * @brief A class which represents the application as an object. * * In order to create a new OFApplication, you should create a class conforming * 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; OFArray OF_GENERIC(OFString *) *_arguments; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_environment; |
︙ | ︙ | |||
198 199 200 201 202 203 204 | /** * @brief The delegate of the application. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id <OFApplicationDelegate> delegate; #ifdef OF_HAVE_SANDBOX | < < < < < < < | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | /** * @brief The delegate of the application. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id <OFApplicationDelegate> delegate; #ifdef OF_HAVE_SANDBOX @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFSandbox *activeSandbox; @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFSandbox *activeSandboxForChildProcesses; #endif /** * @brief Returns the only OFApplication instance in the application. * |
︙ | ︙ | |||
251 252 253 254 255 256 257 | * @brief Terminates the application with the specified status. * * @param status The status with which the application will terminate */ + (void)terminateWithStatus: (int)status OF_NO_RETURN; #ifdef OF_HAVE_SANDBOX | < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < | | 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | * @brief Terminates the application with the specified status. * * @param status The status with which the application will terminate */ + (void)terminateWithStatus: (int)status OF_NO_RETURN; #ifdef OF_HAVE_SANDBOX + (void)of_activateSandbox: (OFSandbox *)sandbox; + (void)of_activateSandboxForChildProcesses: (OFSandbox *)sandbox; #endif - (instancetype)init OF_UNAVAILABLE; /** * @brief Gets argc and argv. * |
︙ | ︙ | |||
308 309 310 311 312 313 314 | * @brief Terminates the application with the specified status. * * @param status The status with which the application will terminate */ - (void)terminateWithStatus: (int)status OF_NO_RETURN; #ifdef OF_HAVE_SANDBOX | < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < | | | | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | * @brief Terminates the application with the specified status. * * @param status The status with which the application will terminate */ - (void)terminateWithStatus: (int)status OF_NO_RETURN; #ifdef OF_HAVE_SANDBOX - (void)of_activateSandbox: (OFSandbox *)sandbox; - (void)of_activateSandboxForChildProcesses: (OFSandbox *)sandbox; #endif @end #ifdef __cplusplus extern "C" { #endif extern int OFApplicationMain(int *_Nonnull, char *_Nullable *_Nonnull[_Nonnull], id <OFApplicationDelegate>); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFApplication.m from [ba8b4a32b1] to [bde88848cd].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #import "OFArray.h" #import "OFDictionary.h" #ifdef OF_AMIGAOS # import "OFFile.h" # import "OFFileManager.h" #endif #import "OFLocale.h" #import "OFPair.h" #import "OFRunLoop+Private.h" #import "OFRunLoop.h" #import "OFSandbox.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFThread+Private.h" | > | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #import "OFArray.h" #import "OFDictionary.h" #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" #import "OFSystemInfo.h" #import "OFThread+Private.h" |
︙ | ︙ | |||
71 72 73 74 75 76 77 | # include <nds.h> # undef asm #endif OF_DIRECT_MEMBERS @interface OFApplication () - (instancetype)of_init OF_METHOD_FAMILY(init); | | < | > > | > > > > > > | > | < | | > > | < | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | # include <nds.h> # undef asm #endif 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 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 <OFApplicationDelegate> delegate = app.delegate; [[OFNotificationCenter defaultCenter] postNotificationName: OFApplicationWillTerminateNotification object: app]; if ([delegate respondsToSelector: @selector(applicationWillTerminate)]) [delegate applicationWillTerminate]; [delegate release]; #if defined(OF_HAVE_THREADS) && defined(OF_HAVE_SOCKETS) && \ defined(OF_AMIGAOS) && !defined(OF_MORPHOS) OFSocketDeinit(); #endif } int OFApplicationMain(int *argc, char **argv[], id <OFApplicationDelegate> delegate) { #ifdef OF_WINDOWS wchar_t **wargv, **wenvp; int wargc, si = 0; #endif [[OFLocale alloc] init]; app = [[OFApplication alloc] of_init]; #ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) { __wgetmainargs(&wargc, &wargv, &wenvp, _CRT_glob, &si); [app of_setArgumentCount: argc andArgumentValues: argv andWideArgumentCount: wargc andWideArgumentValues: wargv]; } else #endif [app of_setArgumentCount: argc andArgumentValues: argv]; app.delegate = delegate; [app of_run]; [delegate release]; |
︙ | ︙ | |||
197 198 199 200 201 202 203 | sceKernelExitGame(); OF_UNREACHABLE #endif } #ifdef OF_HAVE_SANDBOX | | | | | | | | | < | < | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | sceKernelExitGame(); OF_UNREACHABLE #endif } #ifdef OF_HAVE_SANDBOX + (void)of_activateSandbox: (OFSandbox *)sandbox { [app of_activateSandbox: sandbox]; } + (void)of_activateSandboxForChildProcesses: (OFSandbox *)sandbox { [app of_activateSandboxForChildProcesses: sandbox]; } #endif - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)of_init { self = [super init]; @try { _environment = [[OFMutableDictionary alloc] init]; atexit(atexitHandler); #if defined(OF_WINDOWS) if ([OFSystemInfo isWindowsNT]) { OFChar16 *env, *env0; env = env0 = GetEnvironmentStringsW(); while (*env != 0) { void *pool = objc_autoreleasePoolPush(); OFString *tmp, *key, *value; size_t length, pos; length = OFUTF16StringLength(env); tmp = [OFString stringWithUTF16String: env length: length]; env += length + 1; /* * cmd.exe seems to add some special variables * which start with a "=", even though variable * names are not allowed to contain a "=". */ if ([tmp hasPrefix: @"="]) { objc_autoreleasePoolPop(pool); continue; } pos = [tmp rangeOfString: @"="].location; if (pos == OFNotFound) { fprintf(stderr, "Warning: Invalid environment " "variable: %s\n", tmp.UTF8String); continue; } key = [tmp substringToIndex: pos]; value = [tmp substringFromIndex: pos + 1]; [_environment setObject: value forKey: key]; objc_autoreleasePoolPop(pool); } FreeEnvironmentStringsW(env0); } else { char *env, *env0; |
︙ | ︙ | |||
292 293 294 295 296 297 298 | */ if ([tmp hasPrefix: @"="]) { objc_autoreleasePoolPop(pool); continue; } pos = [tmp rangeOfString: @"="].location; | | < | < | | < | < | 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | */ if ([tmp hasPrefix: @"="]) { objc_autoreleasePoolPop(pool); continue; } pos = [tmp rangeOfString: @"="].location; if (pos == OFNotFound) { fprintf(stderr, "Warning: Invalid environment " "variable: %s\n", tmp.UTF8String); continue; } key = [tmp substringToIndex: pos]; value = [tmp substringFromIndex: pos + 1]; [_environment setObject: value forKey: key]; objc_autoreleasePoolPop(pool); } FreeEnvironmentStringsA(env0); } #elif defined(OF_AMIGAOS) void *pool = objc_autoreleasePoolPush(); OFFileManager *fileManager = [OFFileManager defaultManager]; OFArray *envContents = [fileManager contentsOfDirectoryAtPath: @"ENV:"]; OFStringEncoding encoding = [OFLocale encoding]; struct Process *proc; struct LocalVar *firstLocalVar; for (OFString *name in envContents) { void *pool2 = objc_autoreleasePoolPush(); OFString *path, *value; OFFile *file; if ([name containsString: @"."]) continue; path = [@"ENV:" stringByAppendingString: name]; if ([fileManager directoryExistsAtPath: path]) continue; file = [OFFile fileWithPath: path mode: @"r"]; value = [file readLineWithEncoding: encoding]; if (value != nil) [_environment setObject: value forKey: name]; objc_autoreleasePoolPop(pool2); } /* Local variables override global variables */ proc = (struct Process *)FindTask(NULL); firstLocalVar = (struct LocalVar *)proc->pr_LocalVars.mlh_Head; |
︙ | ︙ | |||
371 372 373 374 375 376 377 | key = [OFString stringWithCString: iter->lv_Node.ln_Name encoding: encoding]; value = [OFString stringWithCString: (const char *)iter->lv_Value encoding: encoding length: length]; | < | < < | < | < | < | < | < | < | < | 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | key = [OFString stringWithCString: iter->lv_Node.ln_Name encoding: encoding]; value = [OFString stringWithCString: (const char *)iter->lv_Value encoding: encoding length: length]; [_environment setObject: value forKey: key]; } objc_autoreleasePoolPop(pool); #elif !defined(OF_IOS) # ifndef OF_MACOS char **env = environ; # else char **env = *_NSGetEnviron(); # endif if (env != NULL) { OFStringEncoding encoding = [OFLocale encoding]; for (; *env != NULL; env++) { void *pool = objc_autoreleasePoolPush(); OFString *key, *value; char *sep; if ((sep = strchr(*env, '=')) == NULL) { fprintf(stderr, "Warning: Invalid " "environment variable: %s\n", *env); continue; } key = [OFString stringWithCString: *env encoding: encoding length: sep - *env]; value = [OFString stringWithCString: sep + 1 encoding: encoding]; [_environment setObject: value forKey: key]; objc_autoreleasePoolPop(pool); } } #else /* * iOS does not provide environ and Apple does not allow using * _NSGetEnviron on iOS. Therefore, we just get a few common * variables from the environment which applications might * expect. */ void *pool = objc_autoreleasePoolPush(); char *env; if ((env = getenv("HOME")) != NULL) { OFString *home = [[[OFString alloc] initWithUTF8StringNoCopy: env freeWhenDone: false] autorelease]; [_environment setObject: home forKey: @"HOME"]; } if ((env = getenv("PATH")) != NULL) { OFString *path = [[[OFString alloc] initWithUTF8StringNoCopy: env freeWhenDone: false] autorelease]; [_environment setObject: path forKey: @"PATH"]; } if ((env = getenv("SHELL")) != NULL) { OFString *shell = [[[OFString alloc] initWithUTF8StringNoCopy: env freeWhenDone: false] autorelease]; [_environment setObject: shell forKey: @"SHELL"]; } if ((env = getenv("TMPDIR")) != NULL) { OFString *tmpdir = [[[OFString alloc] initWithUTF8StringNoCopy: env freeWhenDone: false] autorelease]; [_environment setObject: tmpdir forKey: @"TMPDIR"]; } if ((env = getenv("USER")) != NULL) { OFString *user = [[[OFString alloc] initWithUTF8StringNoCopy: env freeWhenDone: false] autorelease]; [_environment setObject: user forKey: @"USER"]; } objc_autoreleasePoolPop(pool); #endif [_environment makeImmutable]; } @catch (id e) { |
︙ | ︙ | |||
480 481 482 483 484 485 486 | { [_arguments release]; [_environment release]; [super dealloc]; } | | < | | 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | { [_arguments release]; [_environment release]; [super dealloc]; } - (void)of_setArgumentCount: (int *)argc andArgumentValues: (char **[])argv { void *pool = objc_autoreleasePoolPush(); OFMutableArray *arguments; OFStringEncoding encoding; _argc = argc; _argv = argv; encoding = [OFLocale encoding]; #ifndef OF_NINTENDO_DS |
︙ | ︙ | |||
514 515 516 517 518 519 520 | [arguments makeImmutable]; } objc_autoreleasePoolPop(pool); } #ifdef OF_WINDOWS | | > > | > > > | | | | | < | 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | [arguments makeImmutable]; } objc_autoreleasePoolPop(pool); } #ifdef OF_WINDOWS - (void)of_setArgumentCount: (int *)argc andArgumentValues: (char **[])argv andWideArgumentCount: (int)wargc andWideArgumentValues: (wchar_t *[])wargv { void *pool = objc_autoreleasePoolPush(); OFMutableArray *arguments; _argc = argc; _argv = argv; if (wargc > 0) { _programName = [[OFString alloc] initWithUTF16String: wargv[0]]; arguments = [[OFMutableArray alloc] init]; for (int i = 1; i < wargc; i++) [arguments addObject: [OFString stringWithUTF16String: wargv[i]]]; [arguments makeImmutable]; _arguments = arguments; } objc_autoreleasePoolPop(pool); } #endif - (void)getArgumentCount: (int **)argc andArgumentValues: (char ****)argv { *argc = _argc; *argv = _argv; } - (id <OFApplicationDelegate>)delegate { |
︙ | ︙ | |||
622 623 624 625 626 627 628 | { [self.class terminateWithStatus: status]; OF_UNREACHABLE } #ifdef OF_HAVE_SANDBOX | | | | | | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | { [self.class terminateWithStatus: status]; OF_UNREACHABLE } #ifdef OF_HAVE_SANDBOX - (void)of_activateSandbox: (OFSandbox *)sandbox { # ifdef OF_HAVE_PLEDGE void *pool = objc_autoreleasePoolPush(); OFStringEncoding encoding = [OFLocale encoding]; OFArray OF_GENERIC(OFSandboxUnveilPath) *unveiledPaths; size_t unveiledPathsCount; const char *promises; if (_activeSandbox != nil && sandbox != _activeSandbox) @throw [OFInvalidArgumentException exception]; unveiledPaths = sandbox.unveiledPaths; unveiledPathsCount = unveiledPaths.count; for (size_t i = sandbox->_unveiledPathsIndex; i < unveiledPathsCount; i++) { OFSandboxUnveilPath unveiledPath = [unveiledPaths objectAtIndex: i]; OFString *path = unveiledPath.firstObject; OFString *permissions = unveiledPath.secondObject; if (path == nil || permissions == nil) @throw [OFInvalidArgumentException exception]; |
︙ | ︙ | |||
667 668 669 670 671 672 673 | objc_autoreleasePoolPop(pool); if (_activeSandbox == nil) _activeSandbox = [sandbox retain]; # endif } | | | 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 | objc_autoreleasePoolPop(pool); if (_activeSandbox == nil) _activeSandbox = [sandbox retain]; # endif } - (void)of_activateSandboxForChildProcesses: (OFSandbox *)sandbox { # ifdef OF_HAVE_PLEDGE void *pool = objc_autoreleasePoolPush(); const char *promises; if (_activeSandboxForChildProcesses != nil && sandbox != _activeSandboxForChildProcesses) |
︙ | ︙ |
Modified src/OFArray+Private.h from [fad96984ad] to [9a457a5499].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFArray.h from [60511cb7de] to [f90f803ff9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
33 34 35 36 37 38 39 | OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFString; | > > > > > | > | > | < > > > > > > > > > | < | | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFString; /** * @brief Options for joining the objects of an array. * * This is a bit mask. */ typedef enum { /** Skip empty components */ OFArraySkipEmptyComponents = 1 } OFArrayJoinOptions; /** * @brief Options for sorting an array. * * This is a bit mask. */ typedef enum { /** Sort the array descending */ OFArraySortDescending = 1 } OFArraySortOptions; #ifdef OF_HAVE_BLOCKS /** * @brief A block for enumerating an OFArray. * * @param object The current object * @param index The index of the current object * @param stop A pointer to a variable that can be set to true to stop the * enumeration */ typedef void (^OFArrayEnumerationBlock)(id object, size_t index, bool *stop); /** * @brief A block for filtering an OFArray. * * @param object The object to inspect * @param index The index of the object to inspect * @return Whether the object should be in the filtered array */ typedef bool (^OFArrayFilterBlock)(id object, size_t index); /** * @brief A block for mapping objects to objects in an OFArray. * * @param object The object to map * @param index The index of the object to map * @return The object to map to */ typedef id _Nonnull (^OFArrayMapBlock)(id object, size_t index); /** * @brief A block for folding an OFArray. * * @param left The object to which the object has been folded so far * @param right The object that should be added to the left object * @return The left and right side folded into one object */ typedef id _Nullable (^OFArrayFoldBlock)(id _Nullable left, id right); #endif /** * @class OFArray OFArray.h ObjFW/OFArray.h * * @brief An abstract class for storing objects in an array. * |
︙ | ︙ | |||
166 167 168 169 170 171 172 | * @brief Creates a new OFArray with the objects from the specified C array of * the specified length. * * @param objects A C array of objects * @param count The length of the C array * @return A new autoreleased OFArray */ | < | | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | * @brief Creates a new OFArray with the objects from the specified C array of * the specified length. * * @param objects A C array of objects * @param count The length of the C array * @return A new autoreleased OFArray */ + (instancetype)arrayWithObjects: (ObjectType const _Nonnull *_Nonnull)objects count: (size_t)count; /** * @brief Initializes an OFArray with the specified object. * * @param object An object * @return An initialized OFArray */ |
︙ | ︙ | |||
215 216 217 218 219 220 221 222 223 224 225 226 227 228 | * @param objects A C array of objects * @param count The length of the C array * @return An initialized OFArray */ - (instancetype)initWithObjects: (ObjectType const _Nonnull *_Nonnull)objects count: (size_t)count; /** * @brief Returns the object at the specified index in the array. * * @warning The returned object is *not* retained and autoreleased for * performance reasons! * * @param index The index of the object to return | > > > > > > > | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | * @param objects A C array of objects * @param count The length of the C array * @return An initialized OFArray */ - (instancetype)initWithObjects: (ObjectType const _Nonnull *_Nonnull)objects count: (size_t)count; /** * @brief Returns an OFEnumerator to enumerate through all objects of the array. * * @return An OFEnumerator to enumerate through all objects of the array */ - (OFEnumerator OF_GENERIC(ObjectType) *)objectEnumerator; /** * @brief Returns the object at the specified index in the array. * * @warning The returned object is *not* retained and autoreleased for * performance reasons! * * @param index The index of the object to return |
︙ | ︙ | |||
252 253 254 255 256 257 258 | * @ref setValue:forKey: is called for each object in the array. * * @note A @ref OFNull value is translated to nil! * * @param value The value for the specified key * @param key The key of the value to set */ | | < | | | | | | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | * @ref setValue:forKey: is called for each object in the array. * * @note A @ref OFNull value is translated to nil! * * @param value The value for the specified key * @param key The key of the value to set */ - (void)setValue: (nullable id)value forKey: (OFString *)key; /** * @brief Copies the objects at the specified range to the specified buffer. * * @param buffer The buffer to copy the objects to * @param range The range to copy */ - (void)getObjects: (ObjectType __unsafe_unretained _Nonnull *_Nonnull)buffer inRange: (OFRange)range; /** * @brief Returns the index of the first object that is equivalent to the * specified object or `OFNotFound` if it was not found. * * @param object The object whose index is returned * @return The index of the first object equivalent to the specified object * or `OFNotFound` if it was not found */ - (size_t)indexOfObject: (ObjectType)object; /** * @brief Returns the index of the first object that has the same address as the * specified object or `OFNotFound` if it was not found. * * @param object The object whose index is returned * @return The index of the first object that has the same address as * the specified object or `OFNotFound` if it was not found */ - (size_t)indexOfObjectIdenticalTo: (ObjectType)object; /** * @brief Checks whether the array contains an object equal to the specified * object. * |
︙ | ︙ | |||
309 310 311 312 313 314 315 | /** * @brief Returns the objects in the specified range as a new OFArray. * * @param range The range for the subarray * @return The subarray as a new autoreleased OFArray */ | | | < < < < | | < < < < | | 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | /** * @brief Returns the objects in the specified range as a new OFArray. * * @param range The range for the subarray * @return The subarray as a new autoreleased OFArray */ - (OFArray OF_GENERIC(ObjectType) *)objectsInRange: (OFRange)range; /** * @brief Creates a string by joining all objects of the array. * * @param separator The string with which the objects should be joined * @return A string containing all objects joined by the separator */ - (OFString *)componentsJoinedByString: (OFString *)separator; /** * @brief Creates a string by joining all objects of the array. * * @param separator The string with which the objects should be joined * @param options Options according to which the objects should be joined * @return A string containing all objects joined by the separator */ - (OFString *)componentsJoinedByString: (OFString *)separator options: (OFArrayJoinOptions)options; /** * @brief Creates a string by calling the selector on all objects of the array * and joining the strings returned by calling the selector. * * @param separator The string with which the objects should be joined * @param selector The selector to perform on the objects * @return A string containing all objects joined by the separator */ - (OFString *)componentsJoinedByString: (OFString *)separator usingSelector: (SEL)selector; /** * @brief Creates a string by calling the selector on all objects of the array * and joining the strings returned by calling the selector. * * @param separator The string with which the objects should be joined * @param selector The selector to perform on the objects * @param options Options according to which the objects should be joined * @return A string containing all objects joined by the separator */ - (OFString *)componentsJoinedByString: (OFString *)separator usingSelector: (SEL)selector options: (OFArrayJoinOptions)options; /** * @brief Performs the specified selector on all objects in the array. * * @param selector The selector to perform on all objects in the array */ - (void)makeObjectsPerformSelector: (SEL)selector; |
︙ | ︙ | |||
385 386 387 388 389 390 391 | /** * @brief Returns a copy of the array sorted using the specified selector and * options. * * @param selector The selector to use to sort the array. It's signature * should be the same as that of -[compare:]. | | < < < < | > | | < < < < | | < < < < < < < < | | | | | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | /** * @brief Returns a copy of the array sorted using the specified selector and * options. * * @param selector The selector to use to sort the array. It's signature * should be the same as that of -[compare:]. * @param options The options to use when sorting the array * @return A sorted copy of the array */ - (OFArray OF_GENERIC(ObjectType) *) sortedArrayUsingSelector: (SEL)selector options: (OFArraySortOptions)options; #ifdef OF_HAVE_BLOCKS /** * @brief Returns a copy of the array sorted using the specified selector and * options. * * @param comparator The comparator to use to sort the array * @param options The options to use when sorting the array * @return A sorted copy of the array */ - (OFArray OF_GENERIC(ObjectType) *) sortedArrayUsingComparator: (OFComparator)comparator options: (OFArraySortOptions)options; #endif /** * @brief Creates a new array with the specified object added. * * @param object The object to add * @return A new array with the specified object added */ - (OFArray OF_GENERIC(ObjectType) *)arrayByAddingObject: (ObjectType)object; /** * @brief Creates a new array with the objects from the specified array added. * * @param array The array with objects to add * @return A new array with the objects from the specified array added */ - (OFArray OF_GENERIC(ObjectType) *)arrayByAddingObjectsFromArray: (OFArray OF_GENERIC(ObjectType) *)array; #ifdef OF_HAVE_BLOCKS /** * @brief Executes a block for each object. * * @param block The block to execute for each object */ - (void)enumerateObjectsUsingBlock: (OFArrayEnumerationBlock)block; /** * @brief Creates a new array, mapping each object using the specified block. * * @param block A block which maps an object for each object * @return A new, autoreleased OFArray */ - (OFArray *)mappedArrayUsingBlock: (OFArrayMapBlock)block; /** * @brief Creates a new array, only containing the objects for which the block * returns true. * * @param block A block which determines if the object should be in the new * array * @return A new, autoreleased OFArray */ - (OFArray OF_GENERIC(ObjectType) *)filteredArrayUsingBlock: (OFArrayFilterBlock)block; /** * @brief Folds the array to a single object using the specified block. * * If the array is empty, it will return `nil`. * * If there is only one object in the array, that object will be returned and * the block will not be invoked. * * If there are at least two objects, the block is invoked for each object * except the first, where left is always to what the array has already been * folded and right what should be added to left. * * @param block A block which folds two objects into one, which is called for * all objects except the first * @return The array folded to a single object */ - (nullable id)foldUsingBlock: (OFArrayFoldBlock)block; #endif #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef ObjectType #endif @end OF_ASSUME_NONNULL_END |
︙ | ︙ |
Modified src/OFArray.m from [3a99f337b3] to [7359b37923].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
36 37 38 39 40 41 42 | #import "OFOutOfRangeException.h" static struct { Class isa; } placeholder; @interface OFArray () | | > | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #import "OFOutOfRangeException.h" static struct { Class isa; } placeholder; @interface OFArray () - (OFString *) of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options depth: (size_t)depth; @end @interface OFPlaceholderArray: OFArray @end @implementation OFPlaceholderArray - (instancetype)init |
︙ | ︙ | |||
193 194 195 196 197 198 199 | - (instancetype)initWithObjects: (id)firstObject, ... { id ret; va_list arguments; va_start(arguments, firstObject); | | < | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | - (instancetype)initWithObjects: (id)firstObject, ... { id ret; va_list arguments; va_start(arguments, firstObject); ret = [self initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments |
︙ | ︙ | |||
227 228 229 230 231 232 233 | } - (size_t)count { OF_UNRECOGNIZED_SELECTOR } | | < < | | > > | | | | > > > > > | < < | | 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | } - (size_t)count { OF_UNRECOGNIZED_SELECTOR } - (void)getObjects: (id *)buffer inRange: (OFRange)range { for (size_t i = 0; i < range.length; i++) buffer[i] = [self objectAtIndex: range.location + i]; } - (id const *)objects { size_t count = self.count; id *buffer = OFAllocMemory(count, sizeof(id)); id const *ret; @try { [self getObjects: buffer inRange: OFRangeMake(0, count)]; ret = [[OFData dataWithItemsNoCopy: buffer count: count itemSize: sizeof(id) freeWhenDone: true] items]; } @catch (id e) { OFFreeMemory(buffer); @throw e; } return ret; } - (id)copy { return [self retain]; } |
︙ | ︙ | |||
294 295 296 297 298 299 300 | } [ret makeImmutable]; return ret; } | | < | < | | | | | | | | < < < | | < | < | | | | | | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 | } [ret makeImmutable]; return ret; } - (void)setValue: (id)value forKey: (OFString *)key { for (id object in self) [object setValue: value forKey: key]; } - (size_t)indexOfObject: (id)object { size_t i = 0; if (object == nil) return OFNotFound; for (id objectIter in self) { if ([objectIter isEqual: object]) return i; i++; } return OFNotFound; } - (size_t)indexOfObjectIdenticalTo: (id)object { size_t i = 0; if (object == nil) return OFNotFound; for (id objectIter in self) { if (objectIter == object) return i; i++; } return OFNotFound; } - (bool)containsObject: (id)object { return ([self indexOfObject: object] != OFNotFound); } - (bool)containsObjectIdenticalTo: (id)object { return ([self indexOfObjectIdenticalTo: object] != OFNotFound); } - (id)firstObject { if (self.count > 0) return [self objectAtIndex: 0]; return nil; } - (id)lastObject { size_t count = self.count; if (count > 0) return [self objectAtIndex: count - 1]; return nil; } - (OFArray *)objectsInRange: (OFRange)range { OFArray *ret; id *buffer; if (range.length > SIZE_MAX - range.location || range.location + range.length < self.count) @throw [OFOutOfRangeException exception]; if (![self isKindOfClass: [OFMutableArray class]]) return [OFSubarray arrayWithArray: self range: range]; buffer = OFAllocMemory(range.length, sizeof(*buffer)); @try { [self getObjects: buffer inRange: range]; ret = [OFArray arrayWithObjects: buffer count: range.length]; } @finally { OFFreeMemory(buffer); } return ret; } - (OFString *)componentsJoinedByString: (OFString *)separator { return [self componentsJoinedByString: separator usingSelector: @selector(description) options: 0]; } - (OFString *)componentsJoinedByString: (OFString *)separator options: (OFArrayJoinOptions)options { return [self componentsJoinedByString: separator usingSelector: @selector(description) options: options]; } - (OFString *)componentsJoinedByString: (OFString *)separator usingSelector: (SEL)selector { return [self componentsJoinedByString: separator usingSelector: selector options: 0]; } - (OFString *)componentsJoinedByString: (OFString *)separator usingSelector: (SEL)selector options: (OFArrayJoinOptions)options { OFMutableString *ret; if (separator == nil) @throw [OFInvalidArgumentException exception]; if (self.count == 0) return @""; if (self.count == 1) { OFString *component = [[self objectAtIndex: 0] performSelector: selector]; if (component == nil) @throw [OFInvalidArgumentException exception]; return component; } ret = [OFMutableString string]; if (options & OFArraySkipEmptyComponents) { for (id object in self) { void *pool = objc_autoreleasePoolPush(); OFString *component = [object performSelector: selector]; if (component == nil) @throw [OFInvalidArgumentException exception]; |
︙ | ︙ | |||
513 514 515 516 517 518 519 | return false; return true; } - (unsigned long)hash { | | | | | | < | | | < | > | < | > | | | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); for (id object in self) OFHashAddHash(&hash, [object hash]); OFHashFinalize(&hash); return hash; } - (OFString *)description { void *pool; OFMutableString *ret; if (self.count == 0) return @"()"; pool = objc_autoreleasePoolPush(); ret = [[self componentsJoinedByString: @",\n"] mutableCopy]; @try { [ret prependString: @"(\n"]; [ret replaceOccurrencesOfString: @"\n" withString: @"\n\t"]; [ret appendString: @"\n)"]; } @catch (id e) { [ret release]; @throw e; } objc_autoreleasePoolPop(pool); [ret makeImmutable]; return [ret autorelease]; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; if ([self isKindOfClass: [OFMutableArray class]]) element = [OFXMLElement elementWithName: @"OFMutableArray" namespace: OFSerializationNS]; else element = [OFXMLElement elementWithName: @"OFArray" namespace: OFSerializationNS]; for (id <OFSerialization> object in self) { void *pool2 = objc_autoreleasePoolPush(); [element addChild: object.XMLElementBySerializing]; objc_autoreleasePoolPop(pool2); } [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } - (OFString *)JSONRepresentation { return [self of_JSONRepresentationWithOptions: 0 depth: 0]; } - (OFString *)JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options { return [self of_JSONRepresentationWithOptions: options depth: 0]; } - (OFString *) of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options depth: (size_t)depth { OFMutableString *JSON = [OFMutableString stringWithString: @"["]; void *pool = objc_autoreleasePoolPush(); size_t i, count = self.count; if (options & OFJSONRepresentationOptionPretty) { OFMutableString *indentation = [OFMutableString string]; for (i = 0; i < depth; i++) [indentation appendString: @"\t"]; [JSON appendString: @"\n"]; |
︙ | ︙ | |||
664 665 666 667 668 669 670 | count = self.count; if (count <= 15) { uint8_t tmp = 0x90 | ((uint8_t)count & 0xF); [data addItem: &tmp]; } else if (count <= UINT16_MAX) { uint8_t type = 0xDC; | | | < | | < | < | 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 | count = self.count; if (count <= 15) { uint8_t tmp = 0x90 | ((uint8_t)count & 0xF); [data addItem: &tmp]; } else if (count <= UINT16_MAX) { uint8_t type = 0xDC; uint16_t tmp = OFToBigEndian16((uint16_t)count); [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (count <= UINT32_MAX) { uint8_t type = 0xDD; uint32_t tmp = OFToBigEndian32((uint32_t)count); [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; pool = objc_autoreleasePoolPush(); i = 0; for (id object in self) { void *pool2 = objc_autoreleasePoolPush(); OFData *child; i++; child = [object messagePackRepresentation]; [data addItems: child.items count: child.count]; objc_autoreleasePoolPop(pool2); } assert(i == count); [data makeImmutable]; |
︙ | ︙ | |||
714 715 716 717 718 719 720 | [object performSelector: selector]; } - (void)makeObjectsPerformSelector: (SEL)selector withObject: (id)object { for (id objectIter in self) | | < < < < | < | < < < | | < | < < < < < < | | | < | | 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 | [object performSelector: selector]; } - (void)makeObjectsPerformSelector: (SEL)selector withObject: (id)object { for (id objectIter in self) [objectIter performSelector: selector withObject: object]; } - (OFArray *)sortedArray { OFMutableArray *new = [[self mutableCopy] autorelease]; [new sort]; [new makeImmutable]; return new; } - (OFArray *)sortedArrayUsingSelector: (SEL)selector options: (OFArraySortOptions)options { OFMutableArray *new = [[self mutableCopy] autorelease]; [new sortUsingSelector: selector options: options]; [new makeImmutable]; return new; } #ifdef OF_HAVE_BLOCKS - (OFArray *)sortedArrayUsingComparator: (OFComparator)comparator options: (OFArraySortOptions)options { OFMutableArray *new = [[self mutableCopy] autorelease]; [new sortUsingComparator: comparator options: options]; [new makeImmutable]; return new; } #endif - (OFArray *)reversedArray { OFMutableArray *new = [[self mutableCopy] autorelease]; [new reverse]; [new makeImmutable]; return new; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { OFRange range = OFRangeMake(state->state, count); if (range.length > SIZE_MAX - range.location) @throw [OFOutOfRangeException exception]; if (range.location + range.length > self.count) range.length = self.count - range.location; [self getObjects: objects inRange: range]; if (range.location + range.length > ULONG_MAX) @throw [OFOutOfRangeException exception]; state->state = (unsigned long)(range.location + range.length); state->itemsPtr = objects; state->mutationsPtr = (unsigned long *)self; return (int)range.length; } - (OFEnumerator *)objectEnumerator { return [[[OFArrayEnumerator alloc] initWithArray: self mutationsPtr: NULL] autorelease]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (OFArrayEnumerationBlock)block { size_t i = 0; bool stop = false; for (id object in self) { block(object, i++, &stop); |
︙ | ︙ | |||
822 823 824 825 826 827 828 | { OFMutableArray *ret; if (object == nil) @throw [OFInvalidArgumentException exception]; ret = [[self mutableCopy] autorelease]; | < < < < < < < < < < < < | | < | < | | | < | < | | | | 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | { OFMutableArray *ret; if (object == nil) @throw [OFInvalidArgumentException exception]; ret = [[self mutableCopy] autorelease]; [ret addObject: object]; [ret makeImmutable]; return ret; } - (OFArray *)arrayByAddingObjectsFromArray: (OFArray *)array { OFMutableArray *ret = [[self mutableCopy] autorelease]; [ret addObjectsFromArray: array]; [ret makeImmutable]; return ret; } #ifdef OF_HAVE_BLOCKS - (OFArray *)mappedArrayUsingBlock: (OFArrayMapBlock)block { OFArray *ret; size_t count = self.count; id *tmp = OFAllocMemory(count, sizeof(id)); @try { [self enumerateObjectsUsingBlock: ^ (id object, size_t idx, bool *stop) { tmp[idx] = block(object, idx); }]; ret = [OFArray arrayWithObjects: tmp count: count]; } @finally { OFFreeMemory(tmp); } return ret; } - (OFArray *)filteredArrayUsingBlock: (OFArrayFilterBlock)block { OFArray *ret; size_t count = self.count; id *tmp = OFAllocMemory(count, sizeof(id)); @try { __block size_t i = 0; [self enumerateObjectsUsingBlock: ^ (id object, size_t idx, bool *stop) { if (block(object, idx)) tmp[i++] = object; }]; ret = [OFArray arrayWithObjects: tmp count: i]; } @finally { OFFreeMemory(tmp); } return ret; } - (id)foldUsingBlock: (OFArrayFoldBlock)block { size_t count = self.count; __block id current; if (count == 0) return nil; if (count == 1) return [[[self objectAtIndex: 0] retain] autorelease]; [self enumerateObjectsUsingBlock: ^ (id object, size_t idx, bool *stop) { id new; if (idx == 0) { current = [object retain]; |
︙ | ︙ |
Renamed and modified src/atomic.h [7db74776cf] to src/OFAtomic.h [25c89d25b5].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #import "macros.h" #ifndef OF_HAVE_ATOMIC_OPS # error No atomic operations available! #endif #if !defined(OF_HAVE_THREADS) | > > > > > | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | #import "macros.h" #ifndef OF_HAVE_ATOMIC_OPS # error No atomic operations available! #endif #if !defined(OF_HAVE_THREADS) static OF_INLINE int OFAtomicIntAdd(volatile int *_Nonnull p, int i) { return (*p += i); } static OF_INLINE int32_t OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i) { return (*p += i); } static OF_INLINE void *_Nullable OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i) { return (*(char *volatile *)p += i); } static OF_INLINE int OFAtomicIntSubtract(volatile int *_Nonnull p, int i) { return (*p -= i); } static OF_INLINE int32_t OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i) { return (*p -= i); } static OF_INLINE void *_Nullable OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i) { return (*(char *volatile *)p -= i); } static OF_INLINE int OFAtomicIntIncrease(volatile int *_Nonnull p) { return ++*p; } static OF_INLINE int32_t OFAtomicInt32Increase(volatile int32_t *_Nonnull p) { return ++*p; } static OF_INLINE int OFAtomicIntDecrease(volatile int *_Nonnull p) { return --*p; } static OF_INLINE int32_t OFAtomicInt32Decrease(volatile int32_t *_Nonnull p) { return --*p; } static OF_INLINE unsigned int OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i) { return (*p |= i); } static OF_INLINE uint32_t OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i) { return (*p |= i); } static OF_INLINE unsigned int OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i) { return (*p &= i); } static OF_INLINE uint32_t OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i) { return (*p &= i); } static OF_INLINE unsigned int OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i) { return (*p ^= i); } static OF_INLINE uint32_t OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i) { return (*p ^= i); } static OF_INLINE bool OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n) { if (*p == o) { *p = n; return true; } return false; } static OF_INLINE bool OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n) { if (*p == o) { *p = n; return true; } return false; } static OF_INLINE bool OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p, void *_Nullable o, void *_Nullable n) { if (*p == o) { *p = n; return true; } return false; } static OF_INLINE void OFMemoryBarrier(void) { /* nop */ } static OF_INLINE void OFAcquireMemoryBarrier(void) { /* nop */ } static OF_INLINE void OFReleaseMemoryBarrier(void) { /* nop */ } #elif (defined(OF_X86_64) || defined(OF_X86)) && defined(__GNUC__) # import "platform/x86/OFAtomic.h" #elif defined(OF_POWERPC) && defined(__GNUC__) && !defined(__APPLE_CC__) && \ !defined(OF_AIX) # import "platform/PowerPC/OFAtomic.h" #elif defined(OF_HAVE_ATOMIC_BUILTINS) # import "platform/GCC4.7/OFAtomic.h" #elif defined(OF_HAVE_SYNC_BUILTINS) # import "platform/GCC4/OFAtomic.h" #elif defined(OF_HAVE_OSATOMIC) # import "platform/macOS/OFAtomic.h" #else # error No atomic operations available! #endif |
Renamed and modified src/base64.h [38c87986ea] to src/OFBase64.h [14838b60d0].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | @class OFString; @class OFMutableData; #ifdef __cplusplus extern "C" { #endif | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | @class OFString; @class OFMutableData; #ifdef __cplusplus extern "C" { #endif extern OFString *OFBase64Encode(const void *, size_t); extern bool OFBase64Decode(OFMutableData *, const char *, size_t); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Renamed and modified src/base64.m [91e8757b0a] to src/OFBase64.m [7cc5f21d9d].
1 | /* | < < | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFBase64.h" #import "OFString.h" #import "OFData.h" static const unsigned char encodeTable[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; static const signed char decodeTable[128] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 }; OFString * OFBase64Encode(const void *data, size_t length) { OFMutableString *ret = [OFMutableString string]; uint8_t *buffer = (uint8_t *)data; size_t i; uint8_t rest; char tb[4]; uint32_t sb; rest = length % 3; for (i = 0; i < length - rest; i += 3) { sb = (buffer[i] << 16) | (buffer[i + 1] << 8) | buffer[i + 2]; tb[0] = encodeTable[(sb & 0xFC0000) >> 18]; tb[1] = encodeTable[(sb & 0x03F000) >> 12]; tb[2] = encodeTable[(sb & 0x000FC0) >> 6]; tb[3] = encodeTable[sb & 0x00003F]; [ret appendCString: tb encoding: OFStringEncodingASCII length: 4]; } switch (rest) { case 1: tb[0] = encodeTable[buffer[i] >> 2]; tb[1] = encodeTable[(buffer[i] & 3) << 4]; tb[2] = tb[3] = '='; [ret appendCString: tb encoding: OFStringEncodingASCII length: 4]; break; case 2: sb = (buffer[i] << 16) | (buffer[i + 1] << 8); tb[0] = encodeTable[(sb & 0xFC0000) >> 18]; tb[1] = encodeTable[(sb & 0x03F000) >> 12]; tb[2] = encodeTable[(sb & 0x000FC0) >> 6]; tb[3] = '='; [ret appendCString: tb encoding: OFStringEncodingASCII length: 4]; break; } [ret makeImmutable]; return ret; } bool OFBase64Decode(OFMutableData *data, const char *string, size_t length) { const uint8_t *buffer = (const uint8_t *)string; size_t i; if ((length & 3) != 0) return false; |
︙ | ︙ | |||
123 124 125 126 127 128 129 | return false; if (buffer[i + 2] == '=') count--; if (buffer[i + 3] == '=') count--; | | | | | | < | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | return false; if (buffer[i + 2] == '=') count--; if (buffer[i + 3] == '=') count--; if ((tmp = decodeTable[buffer[i]]) == -1) return false; sb |= tmp << 18; if ((tmp = decodeTable[buffer[i + 1]]) == -1) return false; sb |= tmp << 12; if ((tmp = decodeTable[buffer[i + 2]]) == -1) return false; sb |= tmp << 6; if ((tmp = decodeTable[buffer[i + 3]]) == -1) return false; sb |= tmp; db[0] = (sb & 0xFF0000) >> 16; db[1] = (sb & 0x00FF00) >> 8; db[2] = sb & 0x0000FF; [data addItems: db count: count]; } return true; } |
Modified src/OFBitSetCharacterSet.h from [4ecbca5797] to [6dd7022dff].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFBitSetCharacterSet.m from [a3efdbfddb] to [d65aed83c7].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | - (instancetype)initWithCharactersInString: (OFString *)string { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); | | | | | > | < | > > > > > > > | | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | - (instancetype)initWithCharactersInString: (OFString *)string { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); const OFUnichar *characters = string.characters; size_t length = string.length; for (size_t i = 0; i < length; i++) { OFUnichar c = characters[i]; if (c / CHAR_BIT >= _size) { size_t newSize; if (UINT32_MAX - c < 1) @throw [OFOutOfRangeException exception]; newSize = OFRoundUpToPowerOf2(CHAR_BIT, c + 1) / CHAR_BIT; _bitset = OFResizeMemory(_bitset, newSize, 1); memset(_bitset + _size, '\0', newSize - _size); _size = newSize; } OFBitsetSet(_bitset, c); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { OFFreeMemory(_bitset); [super dealloc]; } - (bool)characterIsMember: (OFUnichar)character { if (character / CHAR_BIT >= _size) return false; return OFBitsetIsSet(_bitset, character); } @end |
Modified src/OFBlock.h from [f83ccaa46b] to [ae09bf0d6b].
1 | /* | < < | < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFBlock OFBlock.h ObjFW/OFBlock.h * * @brief The class for all blocks, since all blocks are also objects. */ |
︙ | ︙ | |||
38 39 40 41 42 43 44 45 46 | OF_SUBCLASSING_RESTRICTED @interface OFGlobalBlock: OFBlock @end OF_SUBCLASSING_RESTRICTED @interface OFMallocBlock: OFBlock @end OF_ASSUME_NONNULL_END | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | OF_SUBCLASSING_RESTRICTED @interface OFGlobalBlock: OFBlock @end OF_SUBCLASSING_RESTRICTED @interface OFMallocBlock: OFBlock @end #ifdef __cplusplus extern "C" { #endif extern void *_Nullable _Block_copy(const void *_Nullable); extern void _Block_release(const void *_Nullable); # if defined(OF_WINDOWS) && \ (defined(OF_NO_SHARED) || defined(OF_COMPILING_OBJFW)) /* * Clang has implicit declarations for these, but they are dllimport. When * compiling ObjFW itself or using it as a static library, these need to be * dllexport. Interestingly, this still works when using it as a shared library. */ extern __declspec(dllexport) struct objc_class _NSConcreteStackBlock; extern __declspec(dllexport) struct objc_class _NSConcreteGlobalBlock; extern __declspec(dllexport) void _Block_object_assign(void *, const void *, const int); extern __declspec(dllexport) void _Block_object_dispose(const void *, const int); # endif #ifdef __cplusplus } #endif #ifndef Block_copy # define Block_copy(...) \ ((__typeof__(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__))) #endif #ifndef Block_release # define Block_release(...) _Block_release((const void *)(__VA_ARGS__)) #endif OF_ASSUME_NONNULL_END |
Modified src/OFBlock.m from [a597363d01] to [0c18ed18b9].
1 | /* | < < | > > > > > > | | | | > | > > > > > | > < | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdint.h> #include <stdlib.h> #include <string.h> #import "OFBlock.h" #ifdef OF_HAVE_ATOMIC_OPS # import "OFAtomic.h" #endif #ifdef OF_HAVE_THREADS # import "OFPlainMutex.h" #endif #import "OFAllocFailedException.h" #import "OFInitializationFailedException.h" #if defined(OF_OBJFW_RUNTIME) # import "runtime/private.h" #endif struct Block { Class isa; int flags; int reserved; void (*invoke)(void *block, ...); struct { unsigned long reserved; unsigned long size; void (*_Nullable copyHelper)(void *dest, void *src); void (*_Nullable disposeHelper)(void *src); const char *signature; } *descriptor; }; struct Byref { Class isa; struct Byref *forwarding; int flags; int size; void (*keepByref)(void *dest, void *src); void (*disposeByref)(void *); }; enum { OFBlockHasCopyDispose = (1 << 25), OFBlockHasCtor = (1 << 26), OFBlockIsGlobal = (1 << 28), OFBlockHasStret = (1 << 29), OFBlockHasSignature = (1 << 30) }; #define OFBlockRefCountMask 0xFFFF enum { OFBlockFieldIsObject = 3, OFBlockFieldIsBlock = 7, OFBlockFieldIsByref = 8, OFBlockFieldIsWeak = 16, OFBlockByrefCaller = 128 }; @protocol RetainRelease - (instancetype)retain; - (void)release; @end #ifdef OF_OBJFW_RUNTIME /* Begin of ObjC module */ static struct objc_class _NSConcreteStackBlock_metaclass = { Nil, Nil, "OFStackBlock", 8, OBJC_CLASS_INFO_METACLASS, sizeof(_NSConcreteStackBlock_metaclass), NULL, NULL }; struct objc_class _NSConcreteStackBlock = { &_NSConcreteStackBlock_metaclass, (Class)(void *)"OFBlock", "OFStackBlock", 8, OBJC_CLASS_INFO_CLASS, sizeof(struct Block), NULL, NULL }; static struct objc_class _NSConcreteGlobalBlock_metaclass = { Nil, Nil, "OFGlobalBlock", 8, OBJC_CLASS_INFO_METACLASS, sizeof(_NSConcreteGlobalBlock_metaclass), NULL, NULL }; struct objc_class _NSConcreteGlobalBlock = { &_NSConcreteGlobalBlock_metaclass, (Class)(void *)"OFBlock", "OFGlobalBlock", 8, OBJC_CLASS_INFO_CLASS, sizeof(struct Block), NULL, NULL }; static struct objc_class _NSConcreteMallocBlock_metaclass = { Nil, Nil, "OFMallocBlock", 8, OBJC_CLASS_INFO_METACLASS, sizeof(_NSConcreteMallocBlock_metaclass), NULL, NULL }; struct objc_class _NSConcreteMallocBlock = { &_NSConcreteMallocBlock_metaclass, (Class)(void *)"OFBlock", "OFMallocBlock", 8, OBJC_CLASS_INFO_CLASS, sizeof(struct Block), NULL, NULL }; static struct { unsigned long unknown; struct objc_selector *selectorRefs; uint16_t classDefsCount, categoryDefsCount; |
︙ | ︙ | |||
152 153 154 155 156 157 158 | #endif static struct { Class isa; } alloc_failed_exception; #ifndef OF_HAVE_ATOMIC_OPS | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | #endif static struct { Class isa; } alloc_failed_exception; #ifndef OF_HAVE_ATOMIC_OPS # define numSpinlocks 8 /* needs to be a power of 2 */ # define SPINLOCK_HASH(p) ((uintptr_t)p >> 4) & (numSpinlocks - 1) static OFSpinlock blockSpinlocks[numSpinlocks]; static OFSpinlock byrefSpinlocks[numSpinlocks]; #endif void * _Block_copy(const void *block_) { struct Block *block = (struct Block *)block_; if ([(id)block isMemberOfClass: (Class)&_NSConcreteStackBlock]) { struct Block *copy; if ((copy = malloc(block->descriptor->size)) == NULL) { alloc_failed_exception.isa = [OFAllocFailedException class]; @throw (OFAllocFailedException *) &alloc_failed_exception; } memcpy(copy, block, block->descriptor->size); object_setClass((id)copy, (Class)&_NSConcreteMallocBlock); copy->flags++; if (block->flags & OFBlockHasCopyDispose) block->descriptor->copyHelper(copy, block); return copy; } if ([(id)block isMemberOfClass: (Class)&_NSConcreteMallocBlock]) { #ifdef OF_HAVE_ATOMIC_OPS OFAtomicIntIncrease(&block->flags); #else unsigned hash = SPINLOCK_HASH(block); OFEnsure(OFSpinlockLock(&blockSpinlocks[hash]) == 0); block->flags++; OFEnsure(OFSpinlockUnlock(&blockSpinlocks[hash]) == 0); #endif } return block; } void _Block_release(const void *block_) { struct Block *block = (struct Block *)block_; if (object_getClass((id)block) != (Class)&_NSConcreteMallocBlock) return; #ifdef OF_HAVE_ATOMIC_OPS if ((OFAtomicIntDecrease(&block->flags) & OFBlockRefCountMask) == 0) { if (block->flags & OFBlockHasCopyDispose) block->descriptor->disposeHelper(block); free(block); } #else unsigned hash = SPINLOCK_HASH(block); OFEnsure(OFSpinlockLock(&blockSpinlocks[hash]) == 0); if ((--block->flags & OFBlockRefCountMask) == 0) { OFEnsure(OFSpinlockUnlock(&blockSpinlocks[hash]) == 0); if (block->flags & OFBlockHasCopyDispose) block->descriptor->disposeHelper(block); free(block); return; } OFEnsure(OFSpinlockUnlock(&blockSpinlocks[hash]) == 0); #endif } void _Block_object_assign(void *dst_, const void *src_, const int flags_) { int flags = flags_ & (OFBlockFieldIsBlock | OFBlockFieldIsObject | OFBlockFieldIsByref); if (src_ == NULL) return; switch (flags) { case OFBlockFieldIsBlock: *(struct Block **)dst_ = _Block_copy(src_); break; case OFBlockFieldIsObject: if (!(flags_ & OFBlockByrefCaller)) *(id *)dst_ = [(id)src_ retain]; break; case OFBlockFieldIsByref:; struct Byref *src = (struct Byref *)src_; struct Byref **dst = (struct Byref **)dst_; src = src->forwarding; if ((src->flags & OFBlockRefCountMask) == 0) { if ((*dst = malloc(src->size)) == NULL) { alloc_failed_exception.isa = [OFAllocFailedException class]; @throw (OFAllocFailedException *) &alloc_failed_exception; } memcpy(*dst, src, src->size); (*dst)->flags = ((*dst)->flags & ~OFBlockRefCountMask) | 1; (*dst)->forwarding = *dst; if (src->flags & OFBlockHasCopyDispose) src->keepByref(*dst, src); #ifdef OF_HAVE_ATOMIC_OPS if (!OFAtomicPointerCompareAndSwap( (void **)&src->forwarding, src, *dst)) { src->disposeByref(*dst); free(*dst); *dst = src->forwarding; } #else unsigned hash = SPINLOCK_HASH(src); OFEnsure(OFSpinlockLock(&byrefSpinlocks[hash]) == 0); if (src->forwarding == src) src->forwarding = *dst; else { src->disposeByref(*dst); free(*dst); *dst = src->forwarding; } OFEnsure(OFSpinlockUnlock(&byrefSpinlocks[hash]) == 0); #endif } else *dst = src; #ifdef OF_HAVE_ATOMIC_OPS OFAtomicIntIncrease(&(*dst)->flags); #else unsigned hash = SPINLOCK_HASH(*dst); OFEnsure(OFSpinlockLock(&byrefSpinlocks[hash]) == 0); (*dst)->flags++; OFEnsure(OFSpinlockUnlock(&byrefSpinlocks[hash]) == 0); #endif break; } } void _Block_object_dispose(const void *object_, const int flags_) { const int flags = flags_ & (OFBlockFieldIsBlock | OFBlockFieldIsObject | OFBlockFieldIsByref); if (object_ == NULL) return; switch (flags) { case OFBlockFieldIsBlock: _Block_release(object_); break; case OFBlockFieldIsObject: if (!(flags_ & OFBlockByrefCaller)) [(id)object_ release]; break; case OFBlockFieldIsByref:; struct Byref *object = (struct Byref *)object_; object = object->forwarding; #ifdef OF_HAVE_ATOMIC_OPS if ((OFAtomicIntDecrease(&object->flags) & OFBlockRefCountMask) == 0) { if (object->flags & OFBlockHasCopyDispose) object->disposeByref(object); free(object); } #else unsigned hash = SPINLOCK_HASH(object); OFEnsure(OFSpinlockLock(&byrefSpinlocks[hash]) == 0); if ((--object->flags & OFBlockRefCountMask) == 0) { OFEnsure(OFSpinlockUnlock(&byrefSpinlocks[hash]) == 0); if (object->flags & OFBlockHasCopyDispose) object->disposeByref(object); free(object); } OFEnsure(OFSpinlockUnlock(&byrefSpinlocks[hash]) == 0); #endif break; } } @implementation OFBlock + (void)load { #ifndef OF_HAVE_ATOMIC_OPS for (size_t i = 0; i < numSpinlocks; i++) if (OFSpinlockNew(&blockSpinlocks[i]) != 0 || OFSpinlockNew(&byrefSpinlocks[i]) != 0) @throw [OFInitializationFailedException exceptionWithClass: self]; #endif #ifdef OF_APPLE_RUNTIME Class tmp; |
︙ | ︙ | |||
435 436 437 438 439 440 441 | } - (instancetype)init { OF_INVALID_INIT_METHOD } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 445 446 447 448 449 450 451 452 453 454 455 456 457 458 | } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)retain { if ([self isMemberOfClass: (Class)&_NSConcreteMallocBlock]) return Block_copy(self); return self; } |
︙ | ︙ | |||
488 489 490 491 492 493 494 | return self; } - (unsigned int)retainCount { if ([self isMemberOfClass: (Class)&_NSConcreteMallocBlock]) | | < | | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | return self; } - (unsigned int)retainCount { if ([self isMemberOfClass: (Class)&_NSConcreteMallocBlock]) return ((struct Block *)self)->flags & OFBlockRefCountMask; return OFMaxRetainCount; } - (void)release { if ([self isMemberOfClass: (Class)&_NSConcreteMallocBlock]) Block_release(self); } - (void)dealloc { OF_DEALLOC_UNSUPPORTED } @end |
Modified src/OFBytesValue.h from [cfc1c393f0] to [ca1dbf0669].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFBytesValue.m from [812d7bedad] to [b331442837].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | - (instancetype)initWithBytes: (const void *)bytes objCType: (const char *)objCType { self = [super init]; @try { | | | | > > > > > > | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | - (instancetype)initWithBytes: (const void *)bytes objCType: (const char *)objCType { self = [super init]; @try { _size = OFSizeOfTypeEncoding(objCType); _objCType = objCType; _bytes = OFAllocMemory(1, _size); memcpy(_bytes, bytes, _size); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { OFFreeMemory(_bytes); [super dealloc]; } - (void)getValue: (void *)value size: (size_t)size { if (size != _size) @throw [OFOutOfRangeException exception]; memcpy(value, _bytes, _size); } @end |
Renamed and modified src/crc16.h [4ab5578211] to src/OFCRC16.h [6bd74791bc].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | #endif #import "macros.h" #ifdef __cplusplus extern "C" { #endif | | | 21 22 23 24 25 26 27 28 29 30 31 32 | #endif #import "macros.h" #ifdef __cplusplus extern "C" { #endif extern uint16_t OFCRC16(uint16_t crc, const void *_Nonnull bytes, size_t length); #ifdef __cplusplus } #endif |
Renamed and modified src/crc16.m [8d831852e3] to src/OFCRC16.m [ba4e599142].
1 | /* | < < | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFCRC16.h" static const uint16_t CRC16Magic = 0xA001; uint16_t OFCRC16(uint16_t CRC, const void *bytes_, size_t length) { const unsigned char *bytes = bytes_; for (size_t i = 0; i < length; i++) { CRC ^= bytes[i]; for (uint8_t j = 0; j < 8; j++) CRC = (CRC >> 1) ^ (CRC16Magic & (~(CRC & 1) + 1)); } return CRC; } |
Renamed and modified src/crc32.h [8683988c03] to src/OFCRC32.h [139d8dccac].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | #endif #import "macros.h" #ifdef __cplusplus extern "C" { #endif | | | 21 22 23 24 25 26 27 28 29 30 31 32 | #endif #import "macros.h" #ifdef __cplusplus extern "C" { #endif extern uint32_t OFCRC32(uint32_t crc, const void *_Nonnull bytes, size_t length); #ifdef __cplusplus } #endif |
Renamed and modified src/crc32.m [04306be63c] to src/OFCRC32.m [b50ad38210].
1 | /* | < < | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFCRC32.h" static const uint32_t CRC32Magic = 0xEDB88320; uint32_t OFCRC32(uint32_t CRC, const void *bytes_, size_t length) { const unsigned char *bytes = bytes_; for (size_t i = 0; i < length; i++) { CRC ^= bytes[i]; for (uint8_t j = 0; j < 8; j++) CRC = (CRC >> 1) ^ (CRC32Magic & (~(CRC & 1) + 1)); } return CRC; } |
Modified src/OFCharacterSet.h from [c111b41606] to [20dd965c47].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
54 55 56 57 58 59 60 | /** * @brief Creates a new character set containing the characters in the specified * range. * * @param range The range of characters for the character set * @return A new OFCharacterSet */ | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | /** * @brief Creates a new character set containing the characters in the specified * range. * * @param range The range of characters for the character set * @return A new OFCharacterSet */ + (instancetype)characterSetWithRange: (OFRange)range; /** * @brief A character set containing all Unicode characters in the category * `Zs` plus CHARACTER TABULATION (U+0009). */ + (OFCharacterSet *)whitespaceCharacterSet; |
︙ | ︙ | |||
78 79 80 81 82 83 84 | /** * @brief Initializes an already allocated character set with the characters in * the specified range. * * @param range The range of characters for the character set * @return An initialized OFCharacterSet */ | | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | /** * @brief Initializes an already allocated character set with the characters in * the specified range. * * @param range The range of characters for the character set * @return An initialized OFCharacterSet */ - (instancetype)initWithRange: (OFRange)range; /** * @brief Returns whether the specified character is a member of the character * set. * * @param character The character that is checked for being a member of the * character set * @return Whether the specified character is a member of the character set. */ - (bool)characterIsMember: (OFUnichar)character; @end OF_ASSUME_NONNULL_END |
Modified src/OFCharacterSet.m from [7a7a3d4551] to [76e8828364].
1 | /* | < < | | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFCharacterSet.h" #import "OFBitSetCharacterSet.h" #import "OFInvertedCharacterSet.h" #import "OFOnce.h" #import "OFRangeCharacterSet.h" @interface OFPlaceholderCharacterSet: OFCharacterSet @end @interface OFWhitespaceCharacterSet: OFCharacterSet @end static struct { |
︙ | ︙ | |||
50 51 52 53 54 55 56 | - (instancetype)initWithCharactersInString: (OFString *)characters { return (id)[[OFBitSetCharacterSet alloc] initWithCharactersInString: characters]; } | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | - (instancetype)initWithCharactersInString: (OFString *)characters { return (id)[[OFBitSetCharacterSet alloc] initWithCharactersInString: characters]; } - (instancetype)initWithRange: (OFRange)range { return (id)[[OFRangeCharacterSet alloc] initWithRange: range]; } - (instancetype)retain { return self; |
︙ | ︙ | |||
98 99 100 101 102 103 104 | + (instancetype)characterSetWithCharactersInString: (OFString *)characters { return [[[self alloc] initWithCharactersInString: characters] autorelease]; } | | | | | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | + (instancetype)characterSetWithCharactersInString: (OFString *)characters { return [[[self alloc] initWithCharactersInString: characters] autorelease]; } + (instancetype)characterSetWithRange: (OFRange)range { return [[[self alloc] initWithRange: range] autorelease]; } + (OFCharacterSet *)whitespaceCharacterSet { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, initWhitespaceCharacterSet); return whitespaceCharacterSet; } - (instancetype)init { if ([self isMemberOfClass: [OFCharacterSet class]]) { |
︙ | ︙ | |||
132 133 134 135 136 137 138 | } - (instancetype)initWithCharactersInString: (OFString *)characters { OF_INVALID_INIT_METHOD } | | | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | } - (instancetype)initWithCharactersInString: (OFString *)characters { OF_INVALID_INIT_METHOD } - (instancetype)initWithRange: (OFRange)range { OF_INVALID_INIT_METHOD } - (bool)characterIsMember: (OFUnichar)character { OF_UNRECOGNIZED_SELECTOR } - (OFCharacterSet *)invertedSet { return [[[OFInvertedCharacterSet alloc] |
︙ | ︙ | |||
166 167 168 169 170 171 172 | - (void)release { } - (unsigned int)retainCount { | | | | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | - (void)release { } - (unsigned int)retainCount { return OFMaxRetainCount; } - (bool)characterIsMember: (OFUnichar)character { switch (character) { case 0x0009: case 0x0020: case 0x00A0: case 0x1680: case 0x2000: |
︙ | ︙ |
Modified src/OFCollection.h from [045f1fdf5c] to [8d8461caff].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | OF_ASSUME_NONNULL_BEGIN /** * @protocol OFCollection OFCollection.h ObjFW/OFCollection.h * * @brief A protocol with methods common for all collections. */ | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | OF_ASSUME_NONNULL_BEGIN /** * @protocol OFCollection OFCollection.h ObjFW/OFCollection.h * * @brief A protocol with methods common for all collections. */ @protocol OFCollection <OFEnumeration, OFFastEnumeration> /** * @brief The number of objects in the collection */ @property (readonly, nonatomic) size_t count; /** * @brief Checks whether the collection contains an object equal to the |
︙ | ︙ |
Modified src/OFColor.h from [b42dcb2b78] to [bce9432d45].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFColor.m from [442896ccaa] to [5191910ddc].
1 | /* | < < | < | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFColor.h" #import "OFOnce.h" #import "OFInvalidArgumentException.h" @implementation OFColor #define PREDEFINED_COLOR(name, redValue, greenValue, blueValue) \ static OFColor *name##Color = nil; \ \ static void \ initPredefinedColor_##name(void) \ { \ name##Color = [[OFColor alloc] initWithRed: redValue \ green: greenValue \ blue: blueValue \ alpha: 1]; \ } \ \ + (OFColor *)name \ { \ static OFOnceControl onceControl = OFOnceControlInitValue; \ OFOnce(&onceControl, initPredefinedColor_##name); \ \ return name##Color; \ } PREDEFINED_COLOR(black, 0.00f, 0.00f, 0.00f) PREDEFINED_COLOR(silver, 0.75f, 0.75f, 0.75f) PREDEFINED_COLOR(grey, 0.50f, 0.50f, 0.50f) PREDEFINED_COLOR(white, 1.00f, 1.00f, 1.00f) PREDEFINED_COLOR(maroon, 0.50f, 0.00f, 0.00f) |
︙ | ︙ | |||
120 121 122 123 124 125 126 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | | | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | return false; return true; } - (unsigned long)hash { unsigned long hash; float tmp; OFHashInit(&hash); tmp = OFToLittleEndianFloat(_red); for (uint_fast8_t i = 0; i < sizeof(float); i++) OFHashAdd(&hash, ((char *)&tmp)[i]); tmp = OFToLittleEndianFloat(_green); for (uint_fast8_t i = 0; i < sizeof(float); i++) OFHashAdd(&hash, ((char *)&tmp)[i]); tmp = OFToLittleEndianFloat(_blue); for (uint_fast8_t i = 0; i < sizeof(float); i++) OFHashAdd(&hash, ((char *)&tmp)[i]); tmp = OFToLittleEndianFloat(_alpha); for (uint_fast8_t i = 0; i < sizeof(float); i++) OFHashAdd(&hash, ((char *)&tmp)[i]); OFHashFinalize(&hash); return hash; } - (void)getRed: (float *)red green: (float *)green blue: (float *)blue |
︙ | ︙ |
Modified src/OFCondition.h from [bee8a8b425] to [b8eb2412a1].
1 | /* | < < | < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFMutex.h" #import "OFPlainCondition.h" OF_ASSUME_NONNULL_BEGIN @class OFDate; /** * @class OFCondition OFCondition.h ObjFW/OFCondition.h * * @brief A class implementing a condition variable for thread synchronization. */ OF_SUBCLASSING_RESTRICTED @interface OFCondition: OFMutex { OFPlainCondition _condition; bool _conditionInitialized; } /** * @brief Creates a new condition. * * @return A new, autoreleased OFCondition |
︙ | ︙ | |||
70 71 72 73 74 75 76 | * * @note Waiting might have been interrupted by a signal. It is thus recommended * to check the condition again after @ref waitForTimeInterval: returned! * * @param timeInterval The time interval until the timeout is reached * @return Whether the condition has been signaled */ | | | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | * * @note Waiting might have been interrupted by a signal. It is thus recommended * to check the condition again after @ref waitForTimeInterval: returned! * * @param timeInterval The time interval until the timeout is reached * @return Whether the condition has been signaled */ - (bool)waitForTimeInterval: (OFTimeInterval)timeInterval; #ifdef OF_AMIGAOS /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast, the timeout is reached or an Exec Signal is received. * * @note This is only available on AmigaOS! * * @param timeInterval The time interval until the timeout is reached * @param signalMask A pointer to a signal mask of Exec Signals to receive. * This is modified and set to the mask of signals received. * @return Whether the condition has been signaled or a signal received */ - (bool)waitForTimeInterval: (OFTimeInterval)timeInterval orExecSignal: (ULONG *)signalMask; #endif /** * @brief Blocks the current thread until another thread calls @ref signal, * @ref broadcast or the timeout is reached. * |
︙ | ︙ | |||
112 113 114 115 116 117 118 | * @note This is only available on AmigaOS! * * @param date The date at which the timeout is reached * @param signalMask A pointer to a signal mask of Exec Signals to receive. * This is modified and set to the mask of signals received. * @return Whether the condition has been signaled or a signal received */ | | < | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | * @note This is only available on AmigaOS! * * @param date The date at which the timeout is reached * @param signalMask A pointer to a signal mask of Exec Signals to receive. * This is modified and set to the mask of signals received. * @return Whether the condition has been signaled or a signal received */ - (bool)waitUntilDate: (OFDate *)date orExecSignal: (ULONG *)signalMask; #endif /** * @brief Signals the next waiting thread to continue. */ - (void)signal; |
︙ | ︙ |
Modified src/OFCondition.m from [24791db544] to [8de6591c81].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
34 35 36 37 38 39 40 | return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; | | > | > | | > > | | > > > | | | > > | | | > | | | < | | | > | | | > | | | < | < | > > | | > > | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; if (OFPlainConditionNew(&_condition) != 0) { Class c = self.class; [self release]; @throw [OFInitializationFailedException exceptionWithClass: c]; } _conditionInitialized = true; return self; } - (void)dealloc { if (_conditionInitialized) { int error = OFPlainConditionFree(&_condition); if (error != 0) { OFEnsure(error == EBUSY); @throw [OFConditionStillWaitingException exceptionWithCondition: self]; } } [super dealloc]; } - (void)wait { int error = OFPlainConditionWait(&_condition, &_mutex); if (error != 0) @throw [OFConditionWaitFailedException exceptionWithCondition: self errNo: error]; } #ifdef OF_AMIGAOS - (void)waitForConditionOrExecSignal: (ULONG *)signalMask { int error = OFPlainConditionWaitOrExecSignal(&_condition, &_mutex, signalMask); if (error != 0) @throw [OFConditionWaitFailedException exceptionWithCondition: self errNo: error]; } #endif - (bool)waitForTimeInterval: (OFTimeInterval)timeInterval { int error = OFPlainConditionTimedWait(&_condition, &_mutex, timeInterval); if (error == ETIMEDOUT) return false; if (error != 0) @throw [OFConditionWaitFailedException exceptionWithCondition: self errNo: error]; return true; } #ifdef OF_AMIGAOS - (bool)waitForTimeInterval: (OFTimeInterval)timeInterval orExecSignal: (ULONG *)signalMask { int error = OFPlainConditionTimedWaitOrExecSignal(&_condition, &_mutex, timeInterval, signalMask); if (error == ETIMEDOUT) return false; if (error != 0) @throw [OFConditionWaitFailedException exceptionWithCondition: self errNo: error]; return true; } #endif - (bool)waitUntilDate: (OFDate *)date { return [self waitForTimeInterval: date.timeIntervalSinceNow]; } #ifdef OF_AMIGAOS - (bool)waitUntilDate: (OFDate *)date orExecSignal: (ULONG *)signalMask { return [self waitForTimeInterval: date.timeIntervalSinceNow orExecSignal: signalMask]; } #endif - (void)signal { int error = OFPlainConditionSignal(&_condition); if (error != 0) @throw [OFConditionSignalFailedException exceptionWithCondition: self errNo: error]; } - (void)broadcast { int error = OFPlainConditionBroadcast(&_condition); if (error != 0) @throw [OFConditionBroadcastFailedException exceptionWithCondition: self errNo: error]; } @end |
Modified src/OFConstantString.h from [00399dbd51] to [4428a8bf71].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFConstantString.m from [a6f51dcbb3] to [069ffd9312].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
50 51 52 53 54 55 56 | @implementation OFConstantUTF8String + (instancetype)alloc { OF_UNRECOGNIZED_SELECTOR } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | @implementation OFConstantUTF8String + (instancetype)alloc { OF_UNRECOGNIZED_SELECTOR } - (instancetype)retain { return self; } - (instancetype)autorelease { return self; } - (unsigned int)retainCount { return OFMaxRetainCount; } - (void)release { } - (void)dealloc |
︙ | ︙ | |||
133 134 135 136 137 138 139 | objc_registerClassPair((Class)&_OFConstantStringClassReference); #endif } - (void)finishInitialization { @synchronized (self) { | | | < < < | < | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < | | < | < < < < | < | < < < | < | < | | < | < < | < | < | | < | < | | | < | < < < | < | < | | < < < < | < < < | < < < < | < < < < < < < < < < | < | < < | < < < < < < < < < < | < | < | < < | < | < | < < < < < | < < | < < | < < | < | < | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 | objc_registerClassPair((Class)&_OFConstantStringClassReference); #endif } - (void)finishInitialization { @synchronized (self) { struct OFUTF8StringIvars *ivars; if ([self isMemberOfClass: [OFConstantUTF8String class]]) return; ivars = OFAllocZeroedMemory(1, sizeof(*ivars)); ivars->cString = _cString; ivars->cStringLength = _cStringLength; switch (OFUTF8StringCheck(ivars->cString, ivars->cStringLength, &ivars->length)) { case 1: ivars->isUTF8 = true; break; case -1: OFFreeMemory(ivars); @throw [OFInvalidEncodingException exception]; } _cString = (char *)ivars; object_setClass(self, [OFConstantUTF8String class]); } } + (instancetype)alloc { OF_UNRECOGNIZED_SELECTOR } - (instancetype)retain { return self; } - (instancetype)autorelease { return self; } - (unsigned int)retainCount { return OFMaxRetainCount; } - (void)release { } - (void)dealloc { OF_DEALLOC_UNSUPPORTED } /* * In all following methods, the constant string is converted to an * OFConstantUTF8String and the message sent again. */ /* From protocol OFCopying */ - (id)copy { [self finishInitialization]; return [self copy]; } /* From protocol OFMutableCopying */ - (id)mutableCopy { [self finishInitialization]; return [self mutableCopy]; } /* From protocol OFComparing, but overridden in OFString */ - (OFComparisonResult)compare: (OFString *)string { [self finishInitialization]; return [self compare: string]; } /* From OFObject, but reimplemented in OFString */ - (bool)isEqual: (id)object { [self finishInitialization]; return [self isEqual: object]; } - (unsigned long)hash { [self finishInitialization]; return self.hash; } - (OFString *)description { [self finishInitialization]; return self.description; } /* From OFString */ - (const char *)UTF8String { [self finishInitialization]; return self.UTF8String; } - (size_t)getCString: (char *)cString_ maxLength: (size_t)maxLength encoding: (OFStringEncoding)encoding { [self finishInitialization]; return [self getCString: cString_ maxLength: maxLength encoding: encoding]; } - (const char *)cStringWithEncoding: (OFStringEncoding)encoding { [self finishInitialization]; return [self cStringWithEncoding: encoding]; } - (size_t)length { [self finishInitialization]; return self.length; } - (size_t)UTF8StringLength { [self finishInitialization]; return self.UTF8StringLength; } - (size_t)cStringLengthWithEncoding: (OFStringEncoding)encoding { [self finishInitialization]; return [self cStringLengthWithEncoding: encoding]; } - (OFComparisonResult)caseInsensitiveCompare: (OFString *)string { [self finishInitialization]; return [self caseInsensitiveCompare: string]; } - (OFUnichar)characterAtIndex: (size_t)idx { [self finishInitialization]; return [self characterAtIndex: idx]; } - (void)getCharacters: (OFUnichar *)buffer inRange: (OFRange)range { [self finishInitialization]; [self getCharacters: buffer inRange: range]; } - (OFRange)rangeOfString: (OFString *)string { [self finishInitialization]; return [self rangeOfString: string]; } - (OFRange)rangeOfString: (OFString *)string options: (OFStringSearchOptions)options { [self finishInitialization]; return [self rangeOfString: string options: options]; } - (OFRange)rangeOfString: (OFString *)string options: (OFStringSearchOptions)options range: (OFRange)range { [self finishInitialization]; return [self rangeOfString: string options: options range: range]; } - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet { [self finishInitialization]; return [self indexOfCharacterFromSet: characterSet]; } - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet options: (OFStringSearchOptions)options { [self finishInitialization]; return [self indexOfCharacterFromSet: characterSet options: options]; } - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet options: (OFStringSearchOptions)options range: (OFRange)range { [self finishInitialization]; return [self indexOfCharacterFromSet: characterSet options: options range: range]; } - (bool)containsString: (OFString *)string { [self finishInitialization]; return [self containsString: string]; } - (OFString *)substringFromIndex: (size_t)idx { [self finishInitialization]; return [self substringFromIndex: idx]; } - (OFString *)substringToIndex: (size_t)idx { [self finishInitialization]; return [self substringToIndex: idx]; } - (OFString *)substringWithRange: (OFRange)range { [self finishInitialization]; return [self substringWithRange: range]; } - (OFString *)stringByAppendingString: (OFString *)string { [self finishInitialization]; return [self stringByAppendingString: string]; } - (OFString *)stringByAppendingFormat: (OFConstantString *)format arguments: (va_list)arguments { [self finishInitialization]; return [self stringByAppendingFormat: format arguments: arguments]; } - (OFString *)stringByAppendingPathComponent: (OFString *)component { [self finishInitialization]; return [self stringByAppendingPathComponent: component]; } - (OFString *)stringByPrependingString: (OFString *)string { [self finishInitialization]; return [self stringByPrependingString: string]; } - (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string withString: (OFString *)replacement { [self finishInitialization]; return [self stringByReplacingOccurrencesOfString: string withString: replacement]; } - (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (OFRange)range { [self finishInitialization]; return [self stringByReplacingOccurrencesOfString: string withString: replacement options: options range: range]; } - (OFString *)uppercaseString { [self finishInitialization]; return self.uppercaseString; } - (OFString *)lowercaseString { [self finishInitialization]; return self.lowercaseString; } - (OFString *)capitalizedString { [self finishInitialization]; return self.capitalizedString; } - (OFString *)stringByDeletingLeadingWhitespaces { [self finishInitialization]; return self.stringByDeletingLeadingWhitespaces; } - (OFString *)stringByDeletingTrailingWhitespaces { [self finishInitialization]; return self.stringByDeletingTrailingWhitespaces; } - (OFString *)stringByDeletingEnclosingWhitespaces { [self finishInitialization]; return self.stringByDeletingEnclosingWhitespaces; } - (bool)hasPrefix: (OFString *)prefix { [self finishInitialization]; return [self hasPrefix: prefix]; } - (bool)hasSuffix: (OFString *)suffix { [self finishInitialization]; return [self hasSuffix: suffix]; } - (OFArray *)componentsSeparatedByString: (OFString *)delimiter { [self finishInitialization]; return [self componentsSeparatedByString: delimiter]; } - (OFArray *)componentsSeparatedByString: (OFString *)delimiter options: (OFStringSeparationOptions)options { [self finishInitialization]; return [self componentsSeparatedByString: delimiter options: options]; } - (OFArray *) componentsSeparatedByCharactersInSet: (OFCharacterSet *)characterSet { [self finishInitialization]; return [self componentsSeparatedByCharactersInSet: characterSet]; } - (OFArray *) componentsSeparatedByCharactersInSet: (OFCharacterSet *)characterSet options: (OFStringSeparationOptions)options { [self finishInitialization]; return [self componentsSeparatedByCharactersInSet: characterSet options: options]; } - (OFArray *)pathComponents { [self finishInitialization]; return self.pathComponents; } - (OFString *)lastPathComponent { [self finishInitialization]; return self.lastPathComponent; } - (OFString *)stringByDeletingLastPathComponent { [self finishInitialization]; return self.stringByDeletingLastPathComponent; } - (long long)longLongValue { [self finishInitialization]; return self.longLongValue; } - (long long)longLongValueWithBase: (int)base { [self finishInitialization]; return [self longLongValueWithBase: base]; } - (unsigned long long)unsignedLongLongValue { [self finishInitialization]; return self.unsignedLongLongValue; } - (unsigned long long)unsignedLongLongValueWithBase: (int)base { [self finishInitialization]; return [self unsignedLongLongValueWithBase: base]; } - (float)floatValue { [self finishInitialization]; return self.floatValue; } - (double)doubleValue { [self finishInitialization]; return self.doubleValue; } - (const OFUnichar *)characters { [self finishInitialization]; return self.characters; } - (const OFChar16 *)UTF16String { [self finishInitialization]; return self.UTF16String; } - (const OFChar16 *)UTF16StringWithByteOrder: (OFByteOrder)byteOrder { [self finishInitialization]; return [self UTF16StringWithByteOrder: byteOrder]; } - (size_t)UTF16StringLength { [self finishInitialization]; return self.UTF16StringLength; } - (const OFChar32 *)UTF32String { [self finishInitialization]; return self.UTF32String; } - (const OFChar32 *)UTF32StringWithByteOrder: (OFByteOrder)byteOrder { [self finishInitialization]; return [self UTF32StringWithByteOrder: byteOrder]; } - (OFData *)dataWithEncoding: (OFStringEncoding)encoding { [self finishInitialization]; return [self dataWithEncoding: encoding]; } #ifdef OF_HAVE_UNICODE_TABLES - (OFString *)decomposedStringWithCanonicalMapping { [self finishInitialization]; return self.decomposedStringWithCanonicalMapping; } - (OFString *)decomposedStringWithCompatibilityMapping { [self finishInitialization]; return self.decomposedStringWithCompatibilityMapping; } #endif #ifdef OF_WINDOWS - (OFString *)stringByExpandingWindowsEnvironmentStrings { [self finishInitialization]; return self.stringByExpandingWindowsEnvironmentStrings; } #endif #ifdef OF_HAVE_FILES - (void)writeToFile: (OFString *)path { [self finishInitialization]; [self writeToFile: path]; } - (void)writeToFile: (OFString *)path encoding: (OFStringEncoding)encoding { [self finishInitialization]; [self writeToFile: path encoding: encoding]; } #endif - (void)writeToURL: (OFURL *)URL { [self finishInitialization]; [self writeToURL: URL]; } - (void)writeToURL: (OFURL *)URL encoding: (OFStringEncoding)encoding { [self finishInitialization]; [self writeToURL: URL encoding: encoding]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateLinesUsingBlock: (OFStringLineEnumerationBlock)block { [self finishInitialization]; [self enumerateLinesUsingBlock: block]; } #endif @end |
Modified src/OFCountedMapTableSet.h from [32ae18f6b2] to [1da95cb48f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFCountedMapTableSet.m from [72e0c09af3] to [d7ae224517].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
41 42 43 44 45 46 47 | { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if ([set isKindOfClass: [OFCountedSet class]]) { | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if ([set isKindOfClass: [OFCountedSet class]]) { OFCountedSet *countedSet = (OFCountedSet *)set; for (id object in countedSet) { size_t count = [countedSet countForObject: object]; for (size_t i = 0; i < count; i++) [self addObject: object]; |
︙ | ︙ | |||
81 82 83 84 85 86 87 | [self release]; @throw e; } return self; } | | < | < | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | [self release]; @throw e; } return self; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { self = [self init]; @try { for (size_t i = 0; i < count; i++) [self addObject: objects[i]]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { self = [self init]; @try { id object; [self addObject: firstObject]; |
︙ | ︙ | |||
125 126 127 128 129 130 131 | { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: @"OFCountedSet"] || | | | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: @"OFCountedSet"] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; for (OFXMLElement *objectElement in [element elementsForName: @"object" namespace: OFSerializationNS]) { void *pool2 = objc_autoreleasePoolPush(); OFXMLElement *object; OFXMLAttribute *countAttribute; unsigned long long count; object = [objectElement elementsForNamespace: OFSerializationNS].firstObject; countAttribute = [objectElement attributeForName: @"count"]; if (object == nil || countAttribute == nil) @throw [OFInvalidFormatException exception]; count = countAttribute.unsignedLongLongValue; |
︙ | ︙ | |||
169 170 171 172 173 174 175 | - (size_t)countForObject: (id)object { return (size_t)(uintptr_t)[_mapTable objectForKey: object]; } #ifdef OF_HAVE_BLOCKS | | < | < | < | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | - (size_t)countForObject: (id)object { return (size_t)(uintptr_t)[_mapTable objectForKey: object]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsAndCountUsingBlock: (OFCountedSetEnumerationBlock)block { @try { [_mapTable enumerateKeysAndObjectsUsingBlock: ^ (void *key, void *object, bool *stop) { block(key, (size_t)(uintptr_t)object, stop); }]; } @catch (OFEnumerationMutationException *e) { @throw [OFEnumerationMutationException exceptionWithObject: self]; } } #endif - (void)addObject: (id)object { size_t count = (size_t)(uintptr_t)[_mapTable objectForKey: object]; if (SIZE_MAX - count < 1 || UINTPTR_MAX - count < 1) @throw [OFOutOfRangeException exception]; [_mapTable setObject: (void *)(uintptr_t)(count + 1) forKey: object]; } - (void)removeObject: (id)object { size_t count = (size_t)(uintptr_t)[_mapTable objectForKey: object]; if (count == 0) return; count--; if (count > 0) [_mapTable setObject: (void *)(uintptr_t)count forKey: object]; else [_mapTable removeObjectForKey: object]; } - (void)removeAllObjects { [_mapTable removeAllObjects]; } - (void)makeImmutable { } @end |
Modified src/OFCountedSet.h from [9ac0a7e235] to [b22ee9691d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
26 27 28 29 30 31 32 | * @brief A block for enumerating an OFCountedSet. * * @param object The current object * @param count The count of the object * @param stop A pointer to a variable that can be set to true to stop the * enumeration */ | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | * @brief A block for enumerating an OFCountedSet. * * @param object The current object * @param count The count of the object * @param stop A pointer to a variable that can be set to true to stop the * enumeration */ typedef void (^OFCountedSetEnumerationBlock)(id object, size_t count, bool *stop); #endif /** * @class OFCountedSet OFCountedSet.h ObjFW/OFCountedSet.h * * @brief An abstract class for a mutable unordered set of objects, counting how |
︙ | ︙ | |||
57 58 59 60 61 62 63 | #ifdef OF_HAVE_BLOCKS /** * @brief Executes a block for each object in the set. * * @param block The block to execute for each object in the set */ | | < | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #ifdef OF_HAVE_BLOCKS /** * @brief Executes a block for each object in the set. * * @param block The block to execute for each object in the set */ - (void)enumerateObjectsAndCountUsingBlock: (OFCountedSetEnumerationBlock)block; #endif #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef ObjectType #endif @end OF_ASSUME_NONNULL_END |
Modified src/OFCountedSet.m from [e24282a6de] to [985e10aa24].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
57 58 59 60 61 62 63 | ret = [[OFCountedMapTableSet alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } | | < | < | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | ret = [[OFCountedMapTableSet alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { return (id)[[OFCountedMapTableSet alloc] initWithObjects: objects count: count]; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { return (id)[[OFCountedMapTableSet alloc] initWithObject: firstObject arguments: arguments]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { |
︙ | ︙ | |||
158 159 160 161 162 163 164 | [ret appendFormat: @": %zu", [self countForObject: object]]; if (++i < count) [ret appendString: @",\n"]; objc_autoreleasePoolPop(pool2); } | | < < | 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | [ret appendFormat: @": %zu", [self countForObject: object]]; if (++i < count) [ret appendString: @",\n"]; objc_autoreleasePoolPop(pool2); } [ret replaceOccurrencesOfString: @"\n" withString: @"\n\t"]; [ret appendString: @"\n)}"]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } |
︙ | ︙ | |||
185 186 187 188 189 190 191 | - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: @"OFCountedSet" | | | | < | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: @"OFCountedSet" namespace: OFSerializationNS]; for (id <OFSerialization> object in self) { void *pool2 = objc_autoreleasePoolPush(); OFXMLElement *objectElement; OFString *count; count = [OFString stringWithFormat: @"%zu", [self countForObject: object]]; objectElement = [OFXMLElement elementWithName: @"object" namespace: OFSerializationNS]; [objectElement addAttributeWithName: @"count" stringValue: count]; [objectElement addChild: object.XMLElementBySerializing]; [element addChild: objectElement]; objc_autoreleasePoolPop(pool2); } [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsAndCountUsingBlock: (OFCountedSetEnumerationBlock)block { [self enumerateObjectsUsingBlock: ^ (id object, bool *stop) { block(object, [self countForObject: object], stop); }]; } #endif |
︙ | ︙ |
Renamed and modified src/OFCryptoHash.h [ec7cd6aa74] to src/OFCryptographicHash.h [21f208b184].
1 | /* | < < | | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN /** * @protocol OFCryptographicHash \ * OFCryptographicHash.h ObjFW/OFCryptographicHash.h * * @brief A protocol for classes providing cryptographic hash functions. * * A cryptographic hash implementing this protocol can be copied. The entire * state is copied, allowing to calculate a new hash from there. This is * especially useful for generating many hashes with a common prefix. */ @protocol OFCryptographicHash <OFObject, OFCopying> #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) size_t digestSize; @property (class, readonly, nonatomic) size_t blockSize; #endif /** * @brief The digest size of the cryptographic hash, in bytes. |
︙ | ︙ | |||
64 65 66 67 68 69 70 | OF_RETURNS_INNER_POINTER; /** * @brief Creates a new cryptographic hash. * * @return A new autoreleased cryptographic hash */ | < | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | OF_RETURNS_INNER_POINTER; /** * @brief Creates a new cryptographic hash. * * @return A new autoreleased cryptographic hash */ + (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory; /** * @brief Returns the digest size of the cryptographic hash, in bytes. * * @return The digest size of the cryptographic hash, in bytes */ + (size_t)digestSize; |
︙ | ︙ | |||
96 97 98 99 100 101 102 | /** * @brief Adds a buffer to the cryptographic hash to be calculated. * * @param buffer The buffer which should be included into the calculation * @param length The length of the buffer */ | | | > > > > | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | /** * @brief Adds a buffer to the cryptographic hash to be calculated. * * @param buffer The buffer which should be included into the calculation * @param length The length of the buffer */ - (void)updateWithBuffer: (const void *)buffer length: (size_t)length; /** * @brief Performs the final calculation of the cryptographic hash. */ - (void)calculate; /** * @brief Resets all state so that a new hash can be calculated. * * @warning This invalidates any pointer previously returned by @ref digest. If * you are still interested in the previous digest, you need to memcpy * it yourself before calling @ref reset! */ - (void)reset; @end OF_ASSUME_NONNULL_END |
Modified src/OFDNSQuery.h from [1ca5f8c9ce] to [9c2a0f4bc6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
26 27 28 29 30 31 32 | * @class OFDNSQuery OFDNSQuery.h ObjFW/OFDNSQuery.h * * @brief A class representing a DNS query. */ @interface OFDNSQuery: OFObject <OFCopying> { OFString *_domainName; | | | | | | | | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | * @class OFDNSQuery OFDNSQuery.h ObjFW/OFDNSQuery.h * * @brief A class representing a DNS query. */ @interface OFDNSQuery: OFObject <OFCopying> { OFString *_domainName; OFDNSClass _DNSClass; OFDNSRecordType _recordType; OF_RESERVE_IVARS(OFDNSQuery, 4) } /** * @brief The domain name of the query. */ @property (readonly, nonatomic) OFString *domainName; /** * @brief The DNS class of the query. */ @property (readonly, nonatomic) OFDNSClass DNSClass; /** * @brief The record type of the query. */ @property (readonly, nonatomic) OFDNSRecordType recordType; /** * @brief Creates a new, autoreleased OFDNSQuery. * * @param domainName The domain name to query * @param DNSClass The DNS class of the query * @param recordType The record type of the query * @return A new, autoreleased OFDNSQuery */ + (instancetype)queryWithDomainName: (OFString *)domainName DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType; /** * @brief Initializes an already allocated OFDNSQuery. * * @param domainName The domain name to query * @param DNSClass The DNS class of the query * @param recordType The record type of the query * @return An initialized OFDNSQuery */ - (instancetype)initWithDomainName: (OFString *)domainName DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/OFDNSQuery.m from [7b9ce87bc6] to [03ea4234b3].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | #import "OFString.h" @implementation OFDNSQuery @synthesize domainName = _domainName, DNSClass = _DNSClass; @synthesize recordType = _recordType; + (instancetype)queryWithDomainName: (OFString *)domainName | | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #import "OFString.h" @implementation OFDNSQuery @synthesize domainName = _domainName, DNSClass = _DNSClass; @synthesize recordType = _recordType; + (instancetype)queryWithDomainName: (OFString *)domainName DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType { return [[[self alloc] initWithDomainName: domainName DNSClass: DNSClass recordType: recordType] autorelease]; } - (instancetype)initWithDomainName: (OFString *)domainName DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); if (![domainName hasSuffix: @"."]) |
︙ | ︙ | |||
91 92 93 94 95 96 97 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _domainName.hash); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType); OFHashFinalize(&hash); return hash; } - (id)copy { return [self retain]; } - (OFString *)description { return [OFString stringWithFormat: @"<%@ %@ %@ %@>", self.className, _domainName, OFDNSClassName(_DNSClass), OFDNSRecordTypeName(_recordType)]; } @end |
Modified src/OFDNSResolver.h from [0f2597e31a] to [0eee98275d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #import "OFDNSResourceRecord.h" #import "OFDNSResponse.h" #import "OFRunLoop.h" #import "OFString.h" OF_ASSUME_NONNULL_BEGIN | | | | | | | | | | | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #import "OFDNSResourceRecord.h" #import "OFDNSResponse.h" #import "OFRunLoop.h" #import "OFString.h" OF_ASSUME_NONNULL_BEGIN #define OFDNSResolverBufferLength 512 @class OFArray OF_GENERIC(ObjectType); @class OFDNSResolver; @class OFDNSResolverContext; @class OFDNSResolverSettings; @class OFDate; @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFNumber; @class OFTCPSocket; @class OFUDPSocket; /** * @enum OFDNSResolverErrorCode OFDNSResolver.h ObjFW/OFDNSResolver.h * * @brief An enum describing why resolving a host failed. */ typedef enum { /** An unknown error */ OFDNSResolverErrorCodeUnknown, /** The query timed out */ OFDNSResolverErrorCodeTimeout, /** The query was canceled */ OFDNSResolverErrorCodeCanceled, /** * No result for the specified host with the specified type and class. * * This is only used in situations where this is an error, e.g. when * trying to connect to a host. */ OFDNSResolverErrorCodeNoResult, /** The server considered the query to be malformed */ OFDNSResolverErrorCodeServerInvalidFormat, /** The server was unable to process due to an internal error */ OFDNSResolverErrorCodeServerFailure, /** The server returned an error that the domain does not exist */ OFDNSResolverErrorCodeServerNameError, /** The server does not have support for the requested query */ OFDNSResolverErrorCodeServerNotImplemented, /** The server refused the query */ OFDNSResolverErrorCodeServerRefused, /** There was no name server to query */ OFDNSResolverErrorCodeNoNameServer } OFDNSResolverErrorCode; /** * @protocol OFDNSResolverQueryDelegate OFDNSResolver.h ObjFW/OFDNSResolver.h * * @brief A delegate for performed DNS queries. */ @protocol OFDNSResolverQueryDelegate <OFObject> |
︙ | ︙ | |||
99 100 101 102 103 104 105 | @protocol OFDNSResolverHostDelegate <OFObject> /** * @brief This method is called when a DNS resolver resolved a host to * addresses. * * @param resolver The acting resolver * @param host The host the resolver resolved | | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | @protocol OFDNSResolverHostDelegate <OFObject> /** * @brief This method is called when a DNS resolver resolved a host to * addresses. * * @param resolver The acting resolver * @param host The host the resolver resolved * @param addresses OFData containing several OFSocketAddress * @param exception The exception that occurred during resolving, or nil on * success */ - (void)resolver: (OFDNSResolver *)resolver didResolveHost: (OFString *)host addresses: (nullable OFData *)addresses exception: (nullable id)exception; |
︙ | ︙ | |||
127 128 129 130 131 132 133 | @interface OFDNSResolver: OFObject { OFDNSResolverSettings *_settings; OFUDPSocket *_IPv4Socket; #ifdef OF_HAVE_IPV6 OFUDPSocket *_IPv6Socket; #endif | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | @interface OFDNSResolver: OFObject { OFDNSResolverSettings *_settings; OFUDPSocket *_IPv4Socket; #ifdef OF_HAVE_IPV6 OFUDPSocket *_IPv6Socket; #endif char _buffer[OFDNSResolverBufferLength]; OFMutableDictionary OF_GENERIC(OFNumber *, OFDNSResolverContext *) *_queries; OFMutableDictionary OF_GENERIC(OFTCPSocket *, OFDNSResolverContext *) *_TCPQueries; } /** |
︙ | ︙ | |||
163 164 165 166 167 168 169 | */ @property (copy, nonatomic) OFArray OF_GENERIC(OFString *) *searchDomains; /** * @brief The timeout, in seconds, after which the next name server should be * tried. */ | | | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | */ @property (copy, nonatomic) OFArray OF_GENERIC(OFString *) *searchDomains; /** * @brief The timeout, in seconds, after which the next name server should be * tried. */ @property (nonatomic) OFTimeInterval timeout; /** * @brief The number of attempts before giving up to resolve a host. * * Trying all name servers once is considered a single attempt. */ @property (nonatomic) unsigned int maxAttempts; |
︙ | ︙ | |||
187 188 189 190 191 192 193 | @property (nonatomic) bool usesTCP; /** * @brief The interval in seconds in which the config should be reloaded. * * Setting this to 0 disables config reloading. */ | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | @property (nonatomic) bool usesTCP; /** * @brief The interval in seconds in which the config should be reloaded. * * Setting this to 0 disables config reloading. */ @property (nonatomic) OFTimeInterval configReloadInterval; /** * @brief Creates a new, autoreleased OFDNSResolver. */ + (instancetype)resolver; /** |
︙ | ︙ | |||
216 217 218 219 220 221 222 | * @brief Asynchronously performs the specified query. * * @param query The query to perform * @param runLoopMode The run loop mode in which to resolve * @param delegate The delegate to use for callbacks */ - (void)asyncPerformQuery: (OFDNSQuery *)query | | | | | | | | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | * @brief Asynchronously performs the specified query. * * @param query The query to perform * @param runLoopMode The run loop mode in which to resolve * @param delegate The delegate to use for callbacks */ - (void)asyncPerformQuery: (OFDNSQuery *)query runLoopMode: (OFRunLoopMode)runLoopMode delegate: (id <OFDNSResolverQueryDelegate>)delegate; /** * @brief Asynchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param delegate The delegate to use for callbacks */ - (void)asyncResolveAddressesForHost: (OFString *)host delegate: (id <OFDNSResolverHostDelegate>)delegate; /** * @brief Asynchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param addressFamily The desired socket address family * @param delegate The delegate to use for callbacks */ - (void)asyncResolveAddressesForHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily delegate: (id <OFDNSResolverHostDelegate>)delegate; /** * @brief Asynchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param addressFamily The desired socket address family * @param runLoopMode The run loop mode in which to resolve * @param delegate The delegate to use for callbacks */ - (void)asyncResolveAddressesForHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily runLoopMode: (OFRunLoopMode)runLoopMode delegate: (id <OFDNSResolverHostDelegate>)delegate; /** * @brief Synchronously resolves the specified host to socket addresses. * * @param host The host to resolve * @param addressFamily The desired socket address family * @return OFData containing several OFSocketAddress */ - (OFData *)resolveAddressesForHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily; /** * @brief Closes all sockets and cancels all ongoing queries. */ - (void)close; @end OF_ASSUME_NONNULL_END |
Modified src/OFDNSResolver.m from [abd3a40827] to [6722a88381].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #import "OFUDPSocket+Private.h" #import "OFDNSQueryFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #ifndef SOCK_DNS # define SOCK_DNS 0 #endif | > | | < | < | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | #import "OFUDPSocket+Private.h" #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 #endif static const size_t bufferLength = OFDNSResolverBufferLength; static const size_t maxDNSResponseLength = 65536; /* * RFC 1035 doesn't specify if pointers to pointers are allowed, and if so how * many. Since it's unspecified, we have to assume that it might happen, but we * also want to limit it to avoid DoS. Limiting it to 16 levels of pointers and * immediately rejecting pointers to itself seems like a fair balance. */ static const uint_fast8_t maxAllowedPointers = 16; @interface OFDNSResolver () <OFUDPSocketDelegate, OFTCPSocketDelegate> - (void)of_contextTimedOut: (OFDNSResolverContext *)context; @end OF_DIRECT_MEMBERS @interface OFDNSResolverContext: OFObject { @public OFDNSQuery *_query; OFNumber *_ID; OFDNSResolverSettings *_settings; size_t _nameServersIndex; unsigned int _attempt; id <OFDNSResolverQueryDelegate> _delegate; OFData *_queryData; OFSocketAddress _usedNameServer; OFTCPSocket *_TCPSocket; OFMutableData *_TCPQueryData; void *_TCPBuffer; size_t _responseLength; OFTimer *_cancelTimer; } |
︙ | ︙ | |||
166 167 168 169 170 171 172 | [components addObject: component]; } while (componentLength > 0); return [components componentsJoinedByString: @"."]; } static OF_KINDOF(OFDNSResourceRecord *) | | | | | | | | | | | | | | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | [components addObject: component]; } while (componentLength > 0); return [components componentsJoinedByString: @"."]; } static OF_KINDOF(OFDNSResourceRecord *) parseResourceRecord(OFString *name, OFDNSClass DNSClass, OFDNSRecordType recordType, uint32_t TTL, const unsigned char *buffer, size_t length, size_t i, uint16_t dataLength) { if (recordType == OFDNSRecordTypeA && DNSClass == OFDNSClassIN) { OFSocketAddress address; if (dataLength != 4) @throw [OFInvalidServerReplyException exception]; memset(&address, 0, sizeof(address)); address.family = OFSocketAddressFamilyIPv4; address.length = sizeof(address.sockaddr.in); address.sockaddr.in.sin_family = AF_INET; memcpy(&address.sockaddr.in.sin_addr.s_addr, buffer + i, 4); return [[[OFADNSResourceRecord alloc] initWithName: name address: &address TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeNS) { size_t j = i; OFString *authoritativeHost = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFNSDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass authoritativeHost: authoritativeHost TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeCNAME) { size_t j = i; OFString *alias = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFCNAMEDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass alias: alias TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeSOA) { size_t j = i; OFString *primaryNameServer = parseName(buffer, length, &j, maxAllowedPointers); OFString *responsiblePerson; uint32_t serialNumber, refreshInterval, retryInterval; uint32_t expirationInterval, minTTL; if (j > i + dataLength) @throw [OFInvalidServerReplyException exception]; responsiblePerson = parseName(buffer, length, &j, maxAllowedPointers); if (dataLength - (j - i) != 20) @throw [OFInvalidServerReplyException exception]; serialNumber = (buffer[j] << 24) | (buffer[j + 1] << 16) | (buffer[j + 2] << 8) | buffer[j + 3]; refreshInterval = (buffer[j + 4] << 24) | |
︙ | ︙ | |||
254 255 256 257 258 259 260 | responsiblePerson: responsiblePerson serialNumber: serialNumber refreshInterval: refreshInterval retryInterval: retryInterval expirationInterval: expirationInterval minTTL: minTTL TTL: TTL] autorelease]; | | | | | | | | 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | responsiblePerson: responsiblePerson serialNumber: serialNumber refreshInterval: refreshInterval retryInterval: retryInterval expirationInterval: expirationInterval minTTL: minTTL TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypePTR) { size_t j = i; OFString *domainName = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFPTRDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass domainName: domainName TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeHINFO) { size_t j = i; OFString *CPU = parseString(buffer, length, &j); OFString *OS; if (j > i + dataLength) @throw [OFInvalidServerReplyException exception]; OS = parseString(buffer, length, &j); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFHINFODNSResourceRecord alloc] initWithName: name DNSClass: DNSClass CPU: CPU OS: OS TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeMX) { uint16_t preference; size_t j; OFString *mailExchange; if (dataLength < 2) @throw [OFInvalidServerReplyException exception]; preference = (buffer[i] << 8) | buffer[i + 1]; j = i + 2; mailExchange = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFMXDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass preference: preference mailExchange: mailExchange TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeTXT) { OFMutableArray *textStrings = [OFMutableArray array]; while (dataLength > 0) { uint_fast8_t stringLength = buffer[i++]; dataLength--; if (stringLength > dataLength) |
︙ | ︙ | |||
335 336 337 338 339 340 341 | [textStrings makeImmutable]; return [[[OFTXTDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass textStrings: textStrings TTL: TTL] autorelease]; | | | | | | | | | | | | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | [textStrings makeImmutable]; return [[[OFTXTDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass textStrings: textStrings TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeRP) { size_t j = i; OFString *mailbox = parseName(buffer, length, &j, maxAllowedPointers); OFString *TXTDomainName; if (j > i + dataLength) @throw [OFInvalidServerReplyException exception]; TXTDomainName = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFRPDNSResourceRecord alloc] initWithName: name DNSClass: DNSClass mailbox: mailbox TXTDomainName: TXTDomainName TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeAAAA && DNSClass == OFDNSClassIN) { OFSocketAddress address; if (dataLength != 16) @throw [OFInvalidServerReplyException exception]; memset(&address, 0, sizeof(address)); address.family = OFSocketAddressFamilyIPv6; address.length = sizeof(address.sockaddr.in6); #ifdef AF_INET6 address.sockaddr.in6.sin6_family = AF_INET6; #else address.sockaddr.in6.sin6_family = AF_UNSPEC; #endif memcpy(address.sockaddr.in6.sin6_addr.s6_addr, buffer + i, 16); return [[[OFAAAADNSResourceRecord alloc] initWithName: name address: &address TTL: TTL] autorelease]; } else if (recordType == OFDNSRecordTypeSRV && DNSClass == OFDNSClassIN) { uint16_t priority, weight, port; size_t j; OFString *target; if (dataLength < 6) @throw [OFInvalidServerReplyException exception]; priority = (buffer[i] << 8) | buffer[i + 1]; weight = (buffer[i + 2] << 8) | buffer[i + 3]; port = (buffer[i + 4] << 8) | buffer[i + 5]; j = i + 6; target = parseName(buffer, length, &j, maxAllowedPointers); if (j != i + dataLength) @throw [OFInvalidServerReplyException exception]; return [[[OFSRVDNSResourceRecord alloc] initWithName: name priority: priority |
︙ | ︙ | |||
422 423 424 425 426 427 428 | { OFMutableDictionary *ret = [OFMutableDictionary dictionary]; OFEnumerator OF_GENERIC(OFMutableArray *) *objectEnumerator; OFMutableArray *array; for (uint_fast16_t j = 0; j < count; j++) { OFString *name = parseName(buffer, length, i, | | | | | 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 | { OFMutableDictionary *ret = [OFMutableDictionary dictionary]; OFEnumerator OF_GENERIC(OFMutableArray *) *objectEnumerator; OFMutableArray *array; for (uint_fast16_t j = 0; j < count; j++) { OFString *name = parseName(buffer, length, i, maxAllowedPointers); OFDNSClass DNSClass; OFDNSRecordType recordType; uint32_t TTL; uint16_t dataLength; OFDNSResourceRecord *record; if (*i + 10 > length) @throw [OFTruncatedDataException exception]; |
︙ | ︙ | |||
451 452 453 454 455 456 457 | buffer, length, *i, dataLength); *i += dataLength; array = [ret objectForKey: name]; if (array == nil) { array = [OFMutableArray array]; | | < | 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | buffer, length, *i, dataLength); *i += dataLength; array = [ret objectForKey: name]; if (array == nil) { array = [OFMutableArray array]; [ret setObject: array forKey: name]; } [array addObject: record]; } objectEnumerator = [ret objectEnumerator]; while ((array = [objectEnumerator nextObject]) != nil) |
︙ | ︙ | |||
489 490 491 492 493 494 495 | _settings = [settings copy]; _delegate = [delegate retain]; queryData = [OFMutableData dataWithCapacity: 512]; /* Header */ | | | < < | | < < | | < < | 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 | _settings = [settings copy]; _delegate = [delegate retain]; queryData = [OFMutableData dataWithCapacity: 512]; /* Header */ tmp = OFToBigEndian16(_ID.unsignedShortValue); [queryData addItems: &tmp count: 2]; /* RD */ tmp = OFToBigEndian16(1u << 8); [queryData addItems: &tmp count: 2]; /* QDCOUNT */ tmp = OFToBigEndian16(1); [queryData addItems: &tmp count: 2]; /* ANCOUNT, NSCOUNT and ARCOUNT */ [queryData increaseCountBy: 6]; /* Question */ /* QNAME */ for (OFString *component in |
︙ | ︙ | |||
524 525 526 527 528 529 530 | length8 = (uint8_t)length; [queryData addItem: &length8]; [queryData addItems: component.UTF8String count: length]; } /* QTYPE */ | | | < < | | < < | 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 | length8 = (uint8_t)length; [queryData addItem: &length8]; [queryData addItems: component.UTF8String count: length]; } /* QTYPE */ tmp = OFToBigEndian16(_query.recordType); [queryData addItems: &tmp count: 2]; /* QCLASS */ tmp = OFToBigEndian16(_query.DNSClass); [queryData addItems: &tmp count: 2]; [queryData makeImmutable]; _queryData = [queryData copy]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; |
︙ | ︙ | |||
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 | [_query release]; [_ID release]; [_settings release]; [_delegate release]; [_queryData release]; [_TCPSocket release]; [_TCPQueryData release]; [_cancelTimer release]; [super dealloc]; } @end @implementation OFDNSResolver #ifdef OF_AMIGAOS + (void)initialize { if (self != [OFDNSResolver class]) return; | > | | 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 | [_query release]; [_ID release]; [_settings release]; [_delegate release]; [_queryData release]; [_TCPSocket release]; [_TCPQueryData release]; OFFreeMemory(_TCPBuffer); [_cancelTimer release]; [super dealloc]; } @end @implementation OFDNSResolver #ifdef OF_AMIGAOS + (void)initialize { if (self != [OFDNSResolver class]) return; if (!OFSocketInit()) @throw [OFInitializationFailedException exceptionWithClass: self]; } #endif + (instancetype)resolver { |
︙ | ︙ | |||
655 656 657 658 659 660 661 | - (void)setSearchDomains: (OFArray *)searchDomains { OFArray *old = _settings->_searchDomains; _settings->_searchDomains = [searchDomains copy]; [old release]; } | | | | 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 | - (void)setSearchDomains: (OFArray *)searchDomains { OFArray *old = _settings->_searchDomains; _settings->_searchDomains = [searchDomains copy]; [old release]; } - (OFTimeInterval)timeout { return _settings->_timeout; } - (void)setTimeout: (OFTimeInterval)timeout { _settings->_timeout = timeout; } - (unsigned int)maxAttempts { return _settings->_maxAttempts; |
︙ | ︙ | |||
697 698 699 700 701 702 703 | } - (void)setUsesTCP: (bool)usesTCP { _settings->_usesTCP = usesTCP; } | | | | | < | | < | | | | > | > > > | | | > | > > > | | | | | | < | | < | < | < | < | | | 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 | } - (void)setUsesTCP: (bool)usesTCP { _settings->_usesTCP = usesTCP; } - (OFTimeInterval)configReloadInterval { return _settings->_configReloadInterval; } - (void)setConfigReloadInterval: (OFTimeInterval)configReloadInterval { _settings->_configReloadInterval = configReloadInterval; } - (void)of_sendQueryForContext: (OFDNSResolverContext *)context runLoopMode: (OFRunLoopMode)runLoopMode { OFUDPSocket *sock; OFString *nameServer; [_queries setObject: context forKey: context->_ID]; [context->_cancelTimer invalidate]; [context->_cancelTimer release]; context->_cancelTimer = nil; context->_cancelTimer = [[OFTimer alloc] initWithFireDate: [OFDate dateWithTimeIntervalSinceNow: context->_settings->_timeout] interval: context->_settings->_timeout target: self selector: @selector(of_contextTimedOut:) object: context repeats: false]; [[OFRunLoop currentRunLoop] addTimer: context->_cancelTimer forMode: runLoopMode]; nameServer = [context->_settings->_nameServers objectAtIndex: context->_nameServersIndex]; if (context->_settings->_usesTCP) { OFEnsure(context->_TCPSocket == nil); context->_TCPSocket = [[OFTCPSocket alloc] init]; [_TCPQueries setObject: context forKey: context->_TCPSocket]; context->_TCPSocket.delegate = self; [context->_TCPSocket asyncConnectToHost: nameServer port: 53 runLoopMode: runLoopMode]; return; } context->_usedNameServer = OFSocketAddressParseIP(nameServer, 53); switch (context->_usedNameServer.family) { #ifdef OF_HAVE_IPV6 case OFSocketAddressFamilyIPv6: if (_IPv6Socket == nil) { OFSocketAddress address = OFSocketAddressParseIPv6(@"::", 0); _IPv6Socket = [[OFUDPSocket alloc] init]; [_IPv6Socket of_bindToAddress: &address extraType: SOCK_DNS]; @try { _IPv6Socket.canBlock = false; } @catch (OFNotImplementedException *e) { /* Can't do anything about it... */ } _IPv6Socket.delegate = self; } sock = _IPv6Socket; break; #endif case OFSocketAddressFamilyIPv4: if (_IPv4Socket == nil) { OFSocketAddress address = OFSocketAddressParseIPv4(@"0.0.0.0", 0); _IPv4Socket = [[OFUDPSocket alloc] init]; [_IPv4Socket of_bindToAddress: &address extraType: SOCK_DNS]; @try { _IPv4Socket.canBlock = false; } @catch (OFNotImplementedException *e) { /* Can't do anything about it... */ } _IPv4Socket.delegate = self; } sock = _IPv4Socket; break; default: @throw [OFInvalidArgumentException exception]; } [sock asyncSendData: context->_queryData receiver: &context->_usedNameServer runLoopMode: runLoopMode]; [sock asyncReceiveIntoBuffer: _buffer length: bufferLength runLoopMode: runLoopMode]; } - (void)asyncPerformQuery: (OFDNSQuery *)query delegate: (id <OFDNSResolverQueryDelegate>)delegate { [self asyncPerformQuery: query runLoopMode: OFDefaultRunLoopMode delegate: delegate]; } - (void)asyncPerformQuery: (OFDNSQuery *)query runLoopMode: (OFRunLoopMode)runLoopMode delegate: (id <OFDNSResolverQueryDelegate>)delegate { void *pool = objc_autoreleasePoolPush(); OFNumber *ID; OFDNSResolverContext *context; /* Random, unused ID */ do { ID = [OFNumber numberWithUnsignedShort: OFRandom16()]; } while ([_queries objectForKey: ID] != nil); if (query.domainName.UTF8StringLength > 253) @throw [OFOutOfRangeException exception]; if (_settings->_nameServers.count == 0) { id exception = [OFDNSQueryFailedException exceptionWithQuery: query errorCode: OFDNSResolverErrorCodeNoNameServer]; [delegate resolver: self didPerformQuery: query response: nil exception: exception]; return; } context = [[[OFDNSResolverContext alloc] initWithQuery: query ID: ID settings: _settings delegate: delegate] autorelease]; [self of_sendQueryForContext: context runLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } - (void)of_contextTimedOut: (OFDNSResolverContext *)context { OFRunLoopMode runLoopMode = [OFRunLoop currentRunLoop].currentMode; OFDNSQueryFailedException *exception; if (context->_TCPSocket != nil) { context->_TCPSocket.delegate = nil; [context->_TCPSocket cancelAsyncRequests]; [_TCPQueries removeObjectForKey: context->_TCPSocket]; [context->_TCPSocket release]; context->_TCPSocket = nil; context->_responseLength = 0; } if (context->_nameServersIndex + 1 < context->_settings->_nameServers.count) { context->_nameServersIndex++; [self of_sendQueryForContext: context runLoopMode: runLoopMode]; return; } if (++context->_attempt < context->_settings->_maxAttempts) { context->_nameServersIndex = 0; [self of_sendQueryForContext: context runLoopMode: runLoopMode]; return; } context = [[context retain] autorelease]; [_queries removeObjectForKey: context->_ID]; /* * Cancel any pending queries, to avoid a send being still pending and * trying to access the query once it no longer exists. */ [_IPv4Socket cancelAsyncRequests]; [_IPv4Socket asyncReceiveIntoBuffer: _buffer length: bufferLength]; #ifdef OF_HAVE_IPV6 [_IPv6Socket cancelAsyncRequests]; [_IPv6Socket asyncReceiveIntoBuffer: _buffer length: bufferLength]; #endif exception = [OFDNSQueryFailedException exceptionWithQuery: context->_query errorCode: OFDNSResolverErrorCodeTimeout]; [context->_delegate resolver: self didPerformQuery: context->_query response: nil exception: exception]; } - (bool)of_handleResponseBuffer: (unsigned char *)buffer length: (size_t)length sender: (const OFSocketAddress *)sender { OFDictionary *answerRecords = nil, *authorityRecords = nil; OFDictionary *additionalRecords = nil; OFDNSResponse *response = nil; id exception = nil; OFNumber *ID; OFDNSResolverContext *context; |
︙ | ︙ | |||
918 919 920 921 922 923 924 | if (context == nil) return true; if (context->_TCPSocket != nil) { if ([_TCPQueries objectForKey: context->_TCPSocket] != context) return true; | | | | 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 | if (context == nil) return true; if (context->_TCPSocket != nil) { if ([_TCPQueries objectForKey: context->_TCPSocket] != context) return true; } else if (!OFSocketAddressEqual(sender, &context->_usedNameServer)) return true; [context->_cancelTimer invalidate]; [context->_cancelTimer release]; context->_cancelTimer = nil; [_queries removeObjectForKey: ID]; @try { OFDNSResolverErrorCode errorCode = 0; bool tryNextNameServer = false; const unsigned char *queryDataBuffer; size_t i; uint16_t numQuestions, numAnswers, numAuthorityRecords; uint16_t numAdditionalRecords; if (length < 12) |
︙ | ︙ | |||
953 954 955 956 957 958 959 | /* Opcode */ if ((buffer[2] & 0x78) != (queryDataBuffer[2] & 0x78)) @throw [OFInvalidServerReplyException exception]; /* TC */ if (buffer[2] & 0x02) { | | | | | | | | | | | | 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 | /* Opcode */ if ((buffer[2] & 0x78) != (queryDataBuffer[2] & 0x78)) @throw [OFInvalidServerReplyException exception]; /* TC */ if (buffer[2] & 0x02) { OFRunLoopMode runLoopMode; if (context->_settings->_usesTCP) @throw [OFTruncatedDataException exception]; context->_settings->_usesTCP = true; runLoopMode = [OFRunLoop currentRunLoop].currentMode; [self of_sendQueryForContext: context runLoopMode: runLoopMode]; return false; } /* RCODE */ switch (buffer[3] & 0x0F) { case 0: break; case 1: errorCode = OFDNSResolverErrorCodeServerInvalidFormat; break; case 2: errorCode = OFDNSResolverErrorCodeServerFailure; tryNextNameServer = true; break; case 3: errorCode = OFDNSResolverErrorCodeServerNameError; break; case 4: errorCode = OFDNSResolverErrorCodeServerNotImplemented; tryNextNameServer = true; break; case 5: errorCode = OFDNSResolverErrorCodeServerRefused; tryNextNameServer = true; break; default: errorCode = OFDNSResolverErrorCodeUnknown; tryNextNameServer = true; break; } if (tryNextNameServer) { if (context->_nameServersIndex + 1 < context->_settings->_nameServers.count) { OFRunLoopMode runLoopMode = [OFRunLoop currentRunLoop].currentMode; context->_nameServersIndex++; [self of_sendQueryForContext: context runLoopMode: runLoopMode]; return false; } } if (buffer[3] & 0x0F) @throw [OFDNSQueryFailedException exceptionWithQuery: context->_query errorCode: errorCode]; numQuestions = (buffer[4] << 8) | buffer[5]; numAnswers = (buffer[6] << 8) | buffer[7]; numAuthorityRecords = (buffer[8] << 8) | buffer[9]; numAdditionalRecords = (buffer[10] << 8) | buffer[11]; i = 12; /* * Skip over the questions - we use the ID to identify the * query. * * TODO: Compare to our query, just in case? */ for (uint_fast16_t j = 0; j < numQuestions; j++) { parseName(buffer, length, &i, maxAllowedPointers); i += 4; } answerRecords = parseSection(buffer, length, &i, numAnswers); authorityRecords = parseSection(buffer, length, &i, numAuthorityRecords); additionalRecords = parseSection(buffer, length, &i, |
︙ | ︙ | |||
1058 1059 1060 1061 1062 1063 1064 | return false; } - (bool)socket: (OFDatagramSocket *)sock didReceiveIntoBuffer: (void *)buffer length: (size_t)length | | | | 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 | return false; } - (bool)socket: (OFDatagramSocket *)sock didReceiveIntoBuffer: (void *)buffer length: (size_t)length sender: (const OFSocketAddress *)sender exception: (id)exception { if (exception != nil) return true; return [self of_handleResponseBuffer: buffer length: length sender: sender]; } - (void)socket: (OFTCPSocket *)sock didConnectToHost: (OFString *)host port: (uint16_t)port exception: (id)exception { OFDNSResolverContext *context = [_TCPQueries objectForKey: sock]; OFEnsure(context != nil); if (exception != nil) { /* * TODO: Handle error immediately instead of waiting for the * timer to try the next nameserver or to retry. */ [_TCPQueries removeObjectForKey: context->_TCPSocket]; |
︙ | ︙ | |||
1100 1101 1102 1103 1104 1105 1106 | if (queryDataCount > UINT16_MAX) @throw [OFOutOfRangeException exception]; context->_TCPQueryData = [[OFMutableData alloc] initWithCapacity: queryDataCount + 2]; | | | < | | < | < | | | | < < | | | | | | | | 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 | if (queryDataCount > UINT16_MAX) @throw [OFOutOfRangeException exception]; context->_TCPQueryData = [[OFMutableData alloc] initWithCapacity: queryDataCount + 2]; tmp = OFToBigEndian16(queryDataCount); [context->_TCPQueryData addItems: &tmp count: sizeof(tmp)]; [context->_TCPQueryData addItems: context->_queryData.items count: queryDataCount]; } [sock asyncWriteData: context->_TCPQueryData]; } - (OFData *)stream: (OFStream *)stream didWriteData: (OFData *)data bytesWritten: (size_t)bytesWritten exception: (id)exception { OFTCPSocket *sock = (OFTCPSocket *)stream; OFDNSResolverContext *context = [_TCPQueries objectForKey: sock]; OFEnsure(context != nil); if (exception != nil) { /* * TODO: Handle error immediately instead of waiting for the * timer to try the next nameserver or to retry. */ [_TCPQueries removeObjectForKey: context->_TCPSocket]; [context->_TCPSocket release]; context->_TCPSocket = nil; context->_responseLength = 0; return nil; } if (context->_TCPBuffer == nil) context->_TCPBuffer = OFAllocMemory(maxDNSResponseLength, 1); [sock asyncReadIntoBuffer: context->_TCPBuffer exactLength: 2]; return nil; } - (bool)stream: (OFStream *)stream didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (id)exception { OFTCPSocket *sock = (OFTCPSocket *)stream; OFDNSResolverContext *context = [_TCPQueries objectForKey: sock]; OFEnsure(context != nil); if (exception != nil) { /* * TODO: Handle error immediately instead of waiting for the * timer to try the next nameserver or to retry. */ goto done; } if (context->_responseLength == 0) { unsigned char *ucBuffer = buffer; OFEnsure(length == 2); context->_responseLength = (ucBuffer[0] << 8) | ucBuffer[1]; if (context->_responseLength > maxDNSResponseLength) @throw [OFOutOfRangeException exception]; if (context->_responseLength == 0) goto done; [sock asyncReadIntoBuffer: context->_TCPBuffer exactLength: context->_responseLength]; return false; } if (length != context->_responseLength) /* * The connection was closed before we received the entire * response. */ goto done; [self of_handleResponseBuffer: buffer length: length sender: NULL]; done: [_TCPQueries removeObjectForKey: context->_TCPSocket]; [context->_TCPSocket release]; context->_TCPSocket = nil; context->_responseLength = 0; return false; } - (void)asyncResolveAddressesForHost: (OFString *)host delegate: (id <OFDNSResolverHostDelegate>)delegate { [self asyncResolveAddressesForHost: host addressFamily: OFSocketAddressFamilyAny runLoopMode: OFDefaultRunLoopMode delegate: delegate]; } - (void)asyncResolveAddressesForHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily delegate: (id <OFDNSResolverHostDelegate>)delegate { [self asyncResolveAddressesForHost: host addressFamily: addressFamily runLoopMode: OFDefaultRunLoopMode delegate: delegate]; } - (void)asyncResolveAddressesForHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily runLoopMode: (OFRunLoopMode)runLoopMode delegate: (id <OFDNSResolverHostDelegate>)delegate { void *pool = objc_autoreleasePoolPush(); OFHostAddressResolver *resolver = [[[OFHostAddressResolver alloc] initWithHost: host addressFamily: addressFamily resolver: self settings: _settings runLoopMode: runLoopMode delegate: delegate] autorelease]; [resolver asyncResolve]; objc_autoreleasePoolPop(pool); } - (OFData *)resolveAddressesForHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily { void *pool = objc_autoreleasePoolPush(); OFHostAddressResolver *resolver = [[[OFHostAddressResolver alloc] initWithHost: host addressFamily: addressFamily resolver: self settings: _settings |
︙ | ︙ | |||
1277 1278 1279 1280 1281 1282 1283 | enumerator = [_queries objectEnumerator]; while ((context = [enumerator nextObject]) != nil) { OFDNSQueryFailedException *exception; exception = [OFDNSQueryFailedException exceptionWithQuery: context->_query | | | 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 | enumerator = [_queries objectEnumerator]; while ((context = [enumerator nextObject]) != nil) { OFDNSQueryFailedException *exception; exception = [OFDNSQueryFailedException exceptionWithQuery: context->_query errorCode: OFDNSResolverErrorCodeCanceled]; [context->_delegate resolver: self didPerformQuery: context->_query response: nil exception: exception]; } [_queries removeAllObjects]; objc_autoreleasePoolPop(pool); } @end |
Modified src/OFDNSResolverSettings.h from [ff67eea8fc] to [1250cc4b4c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | { @public OFDictionary OF_GENERIC(OFString *, OFArray OF_GENERIC(OFString *) *) *_staticHosts; OFArray OF_GENERIC(OFString *) *_nameServers; OFString *_Nullable _localDomain; OFArray OF_GENERIC(OFString *) *_searchDomains; | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | { @public OFDictionary OF_GENERIC(OFString *, OFArray OF_GENERIC(OFString *) *) *_staticHosts; OFArray OF_GENERIC(OFString *) *_nameServers; OFString *_Nullable _localDomain; OFArray OF_GENERIC(OFString *) *_searchDomains; OFTimeInterval _timeout; unsigned int _maxAttempts, _minNumberOfDotsInAbsoluteName; bool _usesTCP; OFTimeInterval _configReloadInterval; @protected OFDate *_lastConfigReload; } - (void)reload; @end OF_ASSUME_NONNULL_END |
Modified src/OFDNSResolverSettings.m from [7c81772fe9] to [94502fce5f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #import "OFDNSResolverSettings.h" #import "OFArray.h" #import "OFCharacterSet.h" #import "OFDate.h" #import "OFDictionary.h" #import "OFFile.h" #import "OFLocale.h" #import "OFString.h" #ifdef OF_WINDOWS # import "OFWindowsRegistryKey.h" #endif #import "OFInvalidFormatException.h" #import "OFOpenItemFailedException.h" | > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #import "OFDNSResolverSettings.h" #import "OFArray.h" #import "OFCharacterSet.h" #import "OFDate.h" #import "OFDictionary.h" #import "OFFile.h" #import "OFLocale.h" #import "OFSocket+Private.h" #import "OFString.h" #ifdef OF_WINDOWS # import "OFWindowsRegistryKey.h" #endif #import "OFInvalidFormatException.h" #import "OFOpenItemFailedException.h" |
︙ | ︙ | |||
45 46 47 48 49 50 51 | #ifdef OF_NINTENDO_3DS /* Newer versions of libctru started using id as a parameter name. */ # define id id_3ds # include <3ds.h> # undef id #endif | > > | > > < < < | < | | < < < | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | #ifdef OF_NINTENDO_3DS /* Newer versions of libctru started using id as a parameter name. */ # define id id_3ds # include <3ds.h> # undef id #endif #ifdef OF_MORPHOS # include <proto/rexxsyslib.h> # include <rexx/errors.h> # include <rexx/storage.h> #endif #if defined(OF_HAIKU) # define HOSTS_PATH @"/system/settings/network/hosts" # define RESOLV_CONF_PATH @"/system/settings/network/resolv.conf" #elif defined(OF_AMIGAOS4) # define HOSTS_PATH @"DEVS:Internet/hosts" #elif defined(OF_AMIGAOS) # define HOSTS_PATH @"AmiTCP:db/hosts" # define RESOLV_CONF_PATH @"AmiTCP:db/resolv.conf" #else # define HOSTS_PATH @"/etc/hosts" # define RESOLV_CONF_PATH @"/etc/resolv.conf" #endif #ifndef OF_WII static OFString * domainFromHostname(OFString *hostname) { OFString *ret; if (hostname == nil) return nil; @try { OFSocketAddressParseIP(hostname, 0); /* * If we are still here, the host name is a valid IP address. * We can't use that as local domain. */ ret = nil; } @catch (OFInvalidFormatException *e) { /* Not an IP address -> we can use it if it contains a dot. */ size_t pos = [hostname rangeOfString: @"."].location; if (pos != OFNotFound) ret = [hostname substringFromIndex: pos + 1]; else ret = nil; } return ret; } #endif #if !defined(OF_WII) && !defined(OF_MORPHOS) static OFString * obtainHostname(void) { char hostname[256]; if (gethostname(hostname, 256) != 0) return nil; return [OFString stringWithCString: hostname encoding: [OFLocale encoding]]; } #endif #ifdef OF_MORPHOS static OFString * arexxCommand(const char *port, const char *command) { struct Library *RexxSysBase; struct MsgPort *replyPort = NULL; struct RexxMsg *msg = NULL; if ((RexxSysBase = OpenLibrary("rexxsyslib.library", 36)) == NULL) return nil; @try { struct MsgPort *rexxPort; if ((replyPort = CreateMsgPort()) == NULL) return nil; if ((msg = CreateRexxMsg(replyPort, NULL, port)) == NULL) return nil; msg->rm_Action = RXCOMM | RXFF_RESULT; if ((msg->rm_Args[0] = (char *)CreateArgstring( command, strlen(command))) == NULL) return nil; Forbid(); if ((rexxPort = FindPort(port)) == NULL) { Permit(); return nil; } PutMsg(rexxPort, &msg->rm_Node); Permit(); WaitPort(replyPort); GetMsg(replyPort); if (msg->rm_Result1 != RC_OK || msg->rm_Result2 == 0) return nil; return [OFString stringWithCString: (char *)msg->rm_Result2 encoding: [OFLocale encoding]]; } @finally { if (msg != NULL) { if (msg->rm_Args[0] != NULL) DeleteArgstring(msg->rm_Args[0]); if (msg->rm_Result2 != 0) DeleteArgstring((char *)msg->rm_Result2); DeleteRexxMsg(msg); } if (replyPort != NULL) DeleteMsgPort(replyPort); CloseLibrary(RexxSysBase); } } static OFArray OF_GENERIC(OFString *) * parseNetStackArray(OFString *string) { if (![string hasPrefix: @"["] || ![string hasSuffix: @"]"]) return nil; string = [string substringWithRange: OFRangeMake(1, string.length - 2)]; return [string componentsSeparatedByString: @"|"]; } #endif @implementation OFDNSResolverSettings - (void)dealloc { [_staticHosts release]; [_nameServers release]; [_localDomain release]; |
︙ | ︙ | |||
159 160 161 162 163 164 165 | #ifndef OF_NINTENDO_3DS _configReloadInterval = 2; #else _configReloadInterval = 0; #endif } | | < < | < < | | | < < | > | | < | < < < | < < < | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | #ifndef OF_NINTENDO_3DS _configReloadInterval = 2; #else _configReloadInterval = 0; #endif } #if defined(OF_HAVE_FILES) && !defined(OF_MORPHOS) && !defined(OF_NINTENDO_3DS) - (void)parseHosts: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFCharacterSet *whitespaceCharacterSet = [OFCharacterSet whitespaceCharacterSet]; OFMutableDictionary *staticHosts; OFFile *file; OFString *line; @try { file = [OFFile fileWithPath: path mode: @"r"]; } @catch (OFOpenItemFailedException *e) { objc_autoreleasePoolPop(pool); return; } staticHosts = [OFMutableDictionary dictionary]; while ((line = [file readLine]) != nil) { OFArray *components, *hosts; size_t pos; OFString *address; pos = [line rangeOfString: @"#"].location; if (pos != OFNotFound) line = [line substringToIndex: pos]; components = [line componentsSeparatedByCharactersInSet: whitespaceCharacterSet options: OFStringSkipEmptyComponents]; if (components.count < 2) continue; address = components.firstObject; hosts = [components objectsInRange: OFRangeMake(1, components.count - 1)]; for (OFString *host in hosts) { OFMutableArray *addresses = [staticHosts objectForKey: host]; if (addresses == nil) { addresses = [OFMutableArray array]; [staticHosts setObject: addresses forKey: host]; } [addresses addObject: address]; } } for (OFMutableArray *addresses in [staticHosts objectEnumerator]) [addresses makeImmutable]; [staticHosts makeImmutable]; _staticHosts = [staticHosts copy]; objc_autoreleasePoolPop(pool); } # if !defined(OF_WINDOWS) && !defined(OF_AMIGAOS4) - (void)parseResolvConfOption: (OFString *)option |
︙ | ︙ | |||
281 282 283 284 285 286 287 | OFCharacterSet *commentCharacters = [OFCharacterSet characterSetWithCharactersInString: @"#;"]; OFMutableArray *nameServers = [[_nameServers mutableCopy] autorelease]; OFFile *file; OFString *line; @try { | | < | | | | | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | OFCharacterSet *commentCharacters = [OFCharacterSet characterSetWithCharactersInString: @"#;"]; OFMutableArray *nameServers = [[_nameServers mutableCopy] autorelease]; OFFile *file; OFString *line; @try { file = [OFFile fileWithPath: path mode: @"r"]; } @catch (OFOpenItemFailedException *e) { objc_autoreleasePoolPop(pool); return; } if (nameServers == nil) nameServers = [OFMutableArray array]; while ((line = [file readLine]) != nil) { void *pool2 = objc_autoreleasePoolPush(); size_t pos; OFArray *components, *arguments; OFString *option; pos = [line indexOfCharacterFromSet: commentCharacters]; if (pos != OFNotFound) line = [line substringToIndex: pos]; components = [line componentsSeparatedByCharactersInSet: whitespaceCharacterSet options: OFStringSkipEmptyComponents]; if (components.count < 2) { objc_autoreleasePoolPop(pool2); continue; } option = components.firstObject; arguments = [components objectsInRange: OFRangeMake(1, components.count - 1)]; if ([option isEqual: @"nameserver"]) { if (arguments.count != 1) { objc_autoreleasePoolPop(pool2); continue; } [nameServers addObject: arguments.firstObject]; } else if ([option isEqual: @"domain"]) { if (arguments.count != 1) { objc_autoreleasePoolPop(pool2); continue; } [_localDomain release]; |
︙ | ︙ | |||
352 353 354 355 356 357 358 | } # endif #endif #ifdef OF_WINDOWS - (void)obtainWindowsSystemConfig { | | | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 | } # endif #endif #ifdef OF_WINDOWS - (void)obtainWindowsSystemConfig { OFStringEncoding encoding = [OFLocale encoding]; OFMutableArray *nameServers; /* * We need more space than FIXED_INFO in case we have more than one * name server, but we also want it to be properly aligned, meaning we * can't just get a buffer of bytes. Thus, we just get space for 8. */ FIXED_INFO fixedInfo[8]; |
︙ | ︙ | |||
384 385 386 387 388 389 390 391 392 393 394 395 | if (fixedInfo->DomainName[0] != '\0') _localDomain = [[OFString alloc] initWithCString: fixedInfo->DomainName encoding: encoding]; } #endif #ifdef OF_AMIGAOS4 - (void)obtainAmigaOS4SystemConfig { OFMutableArray *nameServers = [OFMutableArray array]; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 | if (fixedInfo->DomainName[0] != '\0') _localDomain = [[OFString alloc] initWithCString: fixedInfo->DomainName encoding: encoding]; } #endif #ifdef OF_MORPHOS - (void)obtainMorphOSSystemConfig { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *staticHosts; _nameServers = [parseNetStackArray(arexxCommand("NETSTACK", "QUERY NAMESERVERS")) copy]; _localDomain = [domainFromHostname(arexxCommand("NETSTACK", "QUERY HOSTNAME")) copy]; _searchDomains = [parseNetStackArray(arexxCommand("NETSTACK", "QUERY DOMAINS")) copy]; staticHosts = [OFMutableDictionary dictionary]; for (OFString *entry in parseNetStackArray(arexxCommand("NETSTACK", "QUERY HOSTS"))) { OFArray *components = [entry componentsSeparatedByString: @" "]; OFString *address; OFArray *hosts; if (components.count < 2) continue; address = components.firstObject; hosts = [components objectsInRange: OFRangeMake(1, components.count - 1)]; for (OFString *host in hosts) { OFMutableArray *addresses = [staticHosts objectForKey: host]; if (addresses == nil) { addresses = [OFMutableArray array]; [staticHosts setObject: addresses forKey: host]; } [addresses addObject: address]; } } for (OFMutableArray *addresses in [staticHosts objectEnumerator]) [addresses makeImmutable]; [staticHosts makeImmutable]; _staticHosts = [staticHosts copy]; objc_autoreleasePoolPop(pool); } #endif #ifdef OF_AMIGAOS4 - (void)obtainAmigaOS4SystemConfig { OFMutableArray *nameServers = [OFMutableArray array]; OFStringEncoding encoding = [OFLocale encoding]; struct List *nameServerList = ObtainDomainNameServerList(); char buffer[MAXHOSTNAMELEN]; if (nameServerList == NULL) @throw [OFOutOfMemoryException exception]; @try { |
︙ | ︙ | |||
454 455 456 457 458 459 460 | * We're fine if this gets smaller in a future release (unlikely), as * long as two entries still fit. */ if (optLen < sizeof(buffer.entries)) return; for (uint_fast8_t i = 0; i < 2; i++) { | | | 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 | * We're fine if this gets smaller in a future release (unlikely), as * long as two entries still fit. */ if (optLen < sizeof(buffer.entries)) return; for (uint_fast8_t i = 0; i < 2; i++) { uint32_t ip = OFFromBigEndian32(buffer.entries[i].ip.s_addr); if (ip == 0) continue; [nameServers addObject: [OFString stringWithFormat: @"%u.%u.%u.%u", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF]]; |
︙ | ︙ | |||
497 498 499 500 501 502 503 | #if defined(OF_WINDOWS) # ifdef OF_HAVE_FILES OFWindowsRegistryKey *key = [[OFWindowsRegistryKey localMachineKey] openSubkeyAtPath: @"SYSTEM\\CurrentControlSet\\Services\\" @"Tcpip\\Parameters" securityAndAccessRights: KEY_QUERY_VALUE]; | | > > | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 | #if defined(OF_WINDOWS) # ifdef OF_HAVE_FILES OFWindowsRegistryKey *key = [[OFWindowsRegistryKey localMachineKey] openSubkeyAtPath: @"SYSTEM\\CurrentControlSet\\Services\\" @"Tcpip\\Parameters" securityAndAccessRights: KEY_QUERY_VALUE]; path = [[[key stringForValueNamed: @"DataBasePath"] stringByAppendingPathComponent: @"hosts"] stringByExpandingWindowsEnvironmentStrings]; if (path != nil) [self parseHosts: path]; # endif [self obtainWindowsSystemConfig]; #elif defined(OF_MORPHOS) [self obtainMorphOSSystemConfig]; #elif defined(OF_AMIGAOS4) [self parseHosts: HOSTS_PATH]; [self obtainAmigaOS4SystemConfig]; #elif defined(OF_NINTENDO_3DS) [self obtainNintendo3DSSytemConfig]; #elif defined(OF_HAVE_FILES) [self parseHosts: HOSTS_PATH]; |
︙ | ︙ | |||
537 538 539 540 541 542 543 | #ifdef OF_HAVE_IPV6 _nameServers = [[OFArray alloc] initWithObjects: @"127.0.0.1", @"::1", nil]; #else _nameServers = [[OFArray alloc] initWithObject: @"127.0.0.1"]; #endif | | | | 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 | #ifdef OF_HAVE_IPV6 _nameServers = [[OFArray alloc] initWithObjects: @"127.0.0.1", @"::1", nil]; #else _nameServers = [[OFArray alloc] initWithObject: @"127.0.0.1"]; #endif #if !defined(OF_WII) && !defined(OF_MORPHOS) if (_localDomain == nil) _localDomain = [domainFromHostname(obtainHostname()) copy]; #endif if (_searchDomains == nil) { if (_localDomain != nil) _searchDomains = [[OFArray alloc] initWithObject: _localDomain]; else _searchDomains = [[OFArray alloc] init]; } objc_autoreleasePoolPop(pool); } @end |
Modified src/OFDNSResourceRecord.h from [4b74104aa3] to [1c8f2631a7].
1 | /* | < < | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFSocket.h" #import "OFString.h" OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFArray OF_GENERIC(ObjectType); @class OFData; /** * @brief The DNS class. */ typedef enum { /** IN */ OFDNSClassIN = 1, /** Any class. Only for queries. */ OFDNSClassAny = 255, } OFDNSClass; /** * @brief The type of a DNS resource record. */ typedef enum { /** A */ OFDNSRecordTypeA = 1, /** NS */ OFDNSRecordTypeNS = 2, /** CNAME */ OFDNSRecordTypeCNAME = 5, /** SOA */ OFDNSRecordTypeSOA = 6, /** PTR */ OFDNSRecordTypePTR = 12, /** HINFO */ OFDNSRecordTypeHINFO = 13, /** MX */ OFDNSRecordTypeMX = 15, /** TXT */ OFDNSRecordTypeTXT = 16, /** RP */ OFDNSRecordTypeRP = 17, /** AAAA */ OFDNSRecordTypeAAAA = 28, /** SRV */ OFDNSRecordTypeSRV = 33, /** All types. Only for queries. */ OFDNSRecordTypeAll = 255, } OFDNSRecordType; /** * @class OFDNSResourceRecord OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing a DNS resource record. */ @interface OFDNSResourceRecord: OFObject <OFCopying> { OFString *_name; OFDNSClass _DNSClass; OFDNSRecordType _recordType; uint32_t _TTL; OF_RESERVE_IVARS(OFDNSResourceRecord, 4) } /** * @brief The domain name to which the resource record belongs. */ @property (readonly, nonatomic) OFString *name; /** * @brief The DNS class. */ @property (readonly, nonatomic) OFDNSClass DNSClass; /** * @brief The resource record type code. */ @property (readonly, nonatomic) OFDNSRecordType recordType; /** * @brief The number of seconds after which the resource record should be * discarded from the cache. */ @property (readonly, nonatomic) uint32_t TTL; /** * @brief Initializes an already allocated OFDNSResourceRecord with the * specified name, class, type, data and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record * @param recordType The type code for the resource record * @param TTL The time to live for the resource record * @return An initialized OFDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end /** * @class OFADNSResourceRecord OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class representing an A DNS resource record. */ OF_SUBCLASSING_RESTRICTED @interface OFADNSResourceRecord: OFDNSResourceRecord { OFSocketAddress _address; } /** * @brief The IPv4 address of the resource record. */ @property (readonly, nonatomic) const OFSocketAddress *address; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFADNSResourceRecord with the * specified name, class, address and time to live. * * @param name The name for the resource record * @param address The address for the resource record * @param TTL The time to live for the resource record * @return An initialized OFADNSResourceRecord */ - (instancetype)initWithName: (OFString *)name address: (const OFSocketAddress *)address TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end /** * @class OFAAAADNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * * @brief A class represenging a DNS resource record. */ OF_SUBCLASSING_RESTRICTED @interface OFAAAADNSResourceRecord: OFDNSResourceRecord { OFSocketAddress _address; } /** * @brief The IPv6 address of the resource record. */ @property (readonly, nonatomic) const OFSocketAddress *address; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFAAAADNSResourceRecord with the * specified name, class, address and time to live. * * @param name The name for the resource record * @param address The address for the resource record * @param TTL The time to live for the resource record * @return An initialized OFAAAADNSResourceRecord */ - (instancetype)initWithName: (OFString *)name address: (const OFSocketAddress *)address TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end /** * @class OFCNAMEDNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h * |
︙ | ︙ | |||
203 204 205 206 207 208 209 | /** * @brief The alias of the resource record. */ @property (readonly, nonatomic) OFString *alias; - (instancetype)initWithName: (OFString *)name | | | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | /** * @brief The alias of the resource record. */ @property (readonly, nonatomic) OFString *alias; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFCNAMEDNSResourceRecord with the * specified name, class, alias and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record * @param alias The alias for the resource record * @param TTL The time to live for the resource record * @return An initialized OFCNAMEDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass alias: (OFString *)alias TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end /** * @class OFHINFODNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h |
︙ | ︙ | |||
246 247 248 249 250 251 252 | /** * @brief The OS of the host info of the resource record. */ @property (readonly, nonatomic) OFString *OS; - (instancetype)initWithName: (OFString *)name | | | | | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | /** * @brief The OS of the host info of the resource record. */ @property (readonly, nonatomic) OFString *OS; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFHINFODNSResourceRecord with the * specified name, class, domain name and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record * @param CPU The CPU of the host info for the resource record * @param OS The OS of the host info for the resource record * @param TTL The time to live for the resource record * @return An initialized OFHINFODNSResourceRecord */ - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass CPU: (OFString *)CPU OS: (OFString *)OS TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end /** * @class OFMXDNSResourceRecord \ |
︙ | ︙ | |||
292 293 294 295 296 297 298 | /** * @brief The mail exchange of the resource record. */ @property (readonly, nonatomic) OFString *mailExchange; - (instancetype)initWithName: (OFString *)name | | | | | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | /** * @brief The mail exchange of the resource record. */ @property (readonly, nonatomic) OFString *mailExchange; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFMXDNSResourceRecord with the * specified name, class, preference, mail exchange and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record * @param preference The preference for the resource record * @param mailExchange The mail exchange for the resource record * @param TTL The time to live for the resource record * @return An initialized OFMXDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass preference: (uint16_t)preference mailExchange: (OFString *)mailExchange TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end /** * @class OFNSDNSResourceRecord \ |
︙ | ︙ | |||
332 333 334 335 336 337 338 | /** * @brief The authoritative host of the resource record. */ @property (readonly, nonatomic) OFString *authoritativeHost; - (instancetype)initWithName: (OFString *)name | | | | | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | /** * @brief The authoritative host of the resource record. */ @property (readonly, nonatomic) OFString *authoritativeHost; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFNSDNSResourceRecord with the * specified name, class, authoritative host and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record * @param authoritativeHost The authoritative host for the resource record * @param TTL The time to live for the resource record * @return An initialized OFNSDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass authoritativeHost: (OFString *)authoritativeHost TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end /** * @class OFPTRDNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h |
︙ | ︙ | |||
370 371 372 373 374 375 376 | /** * @brief The domain name of the resource record. */ @property (readonly, nonatomic) OFString *domainName; - (instancetype)initWithName: (OFString *)name | | | | | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | /** * @brief The domain name of the resource record. */ @property (readonly, nonatomic) OFString *domainName; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFPTRDNSResourceRecord with the * specified name, class, domain name and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record * @param domainName The domain name for the resource record * @param TTL The time to live for the resource record * @return An initialized OFPTRDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass domainName: (OFString *)domainName TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end /** * @class OFRPNSResourceRecord \ * OFDNSResourceRecord.h ObjFW/OFDNSResourceRecord.h |
︙ | ︙ | |||
414 415 416 417 418 419 420 | /** * @brief A domain name that contains a TXT resource record for the responsible * person of the resource record. */ @property (readonly, nonatomic) OFString *TXTDomainName; - (instancetype)initWithName: (OFString *)name | | | | | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | /** * @brief A domain name that contains a TXT resource record for the responsible * person of the resource record. */ @property (readonly, nonatomic) OFString *TXTDomainName; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFRPDNSResourceRecord with the * specified name, class, alias and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record * @param mailbox The mailbox of the responsible person of the resource record * @param TXTDomainName A domain name that contains a TXT resource record for * the responsible person of the resource record * @param TTL The time to live for the resource record * @return An initialized OFRPDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass mailbox: (OFString *)mailbox TXTDomainName: (OFString *)TXTDomainName TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end /** * @class OFSOADNSResourceRecord \ |
︙ | ︙ | |||
487 488 489 490 491 492 493 | /** * @brief The minimum TTL of the zone. */ @property (readonly, nonatomic) uint32_t minTTL; - (instancetype)initWithName: (OFString *)name | | | | | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 | /** * @brief The minimum TTL of the zone. */ @property (readonly, nonatomic) uint32_t minTTL; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFSOADNSResourceRecord with the * specified name, class, text data and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record * @param primaryNameServer The the primary name server for the zone * @param responsiblePerson The mailbox of the person responsible for the zone * @param serialNumber The serial number of the original copy of the zone * @param refreshInterval The refresh interval of the zone * @param retryInterval The retry interval of the zone * @param expirationInterval The expiration interval of the zone * @param minTTL The minimum TTL of the zone * @param TTL The time to live for the resource record * @return An initialized OFSOADNSResourceRecord */ - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass primaryNameServer: (OFString *)primaryNameServer responsiblePerson: (OFString *)responsiblePerson serialNumber: (uint32_t)serialNumber refreshInterval: (uint32_t)refreshInterval retryInterval: (uint32_t)retryInterval expirationInterval: (uint32_t)expirationInterval minTTL: (uint32_t)minTTL |
︙ | ︙ | |||
554 555 556 557 558 559 560 | /** * @brief The port on the target of the resource record. */ @property (readonly, nonatomic) uint16_t port; - (instancetype)initWithName: (OFString *)name | | | | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 | /** * @brief The port on the target of the resource record. */ @property (readonly, nonatomic) uint16_t port; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFSRVDNSResourceRecord with the * specified name, class, preference, mail exchange and time to live. * * @param name The name for the resource record |
︙ | ︙ | |||
596 597 598 599 600 601 602 | /** * @brief The text of the resource record. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFData *) *textStrings; - (instancetype)initWithName: (OFString *)name | | | | > > > > > > | > > > > > > > | | > > > > > > | > > > > > > > | | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 | /** * @brief The text of the resource record. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFData *) *textStrings; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFTXTDNSResourceRecord with the * specified name, class, text data and time to live. * * @param name The name for the resource record * @param DNSClass The class code for the resource record * @param textStrings An array of text strings for the resource record * @param TTL The time to live for the resource record * @return An initialized OFTXTDNSResourceRecord */ - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass textStrings: (OFArray OF_GENERIC(OFData *) *)textStrings TTL: (uint32_t)TTL OF_DESIGNATED_INITIALIZER; @end #ifdef __cplusplus extern "C" { #endif /** * @brief Returns the name for the specified OFDNSClass. * * @param DNSClass The OFDNSClass to return the name for * @return The name for the specified OFDNSClass */ extern OFString *_Nonnull OFDNSClassName(OFDNSClass DNSClass); /** * @brief Returns the name for the specified OFDNSRecordType. * * @param recordType The OFDNSRecordType to return the name for * @return The name for the specified OFDNSRecordType */ extern OFString *_Nonnull OFDNSRecordTypeName(OFDNSRecordType recordType); /** * @brief Parses the specified string as an @ref OFDNSClass. * * @param string The string to parse as an @ref OFDNSClass * @return The parsed OFDNSClass */ extern OFDNSClass OFDNSClassParseName(OFString *_Nonnull string); /** * @brief Parses the specified string as an @ref OFDNSRecordType. * * @param string The string to parse as an @ref OFDNSRecordType * @return The parsed OFDNSRecordType */ extern OFDNSRecordType OFDNSRecordTypeParseName(OFString *_Nonnull string); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFDNSResourceRecord.m from [2126cc3910] to [5aceee5a6c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | #import "OFArray.h" #import "OFData.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" OFString * | | | | | | | | | | | | | | | | | > | | | | > | | | | | | | | | | | | | | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | #import "OFArray.h" #import "OFData.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" OFString * OFDNSClassName(OFDNSClass DNSClass) { switch (DNSClass) { case OFDNSClassIN: return @"IN"; case OFDNSClassAny: return @"any"; default: return [OFString stringWithFormat: @"%u", DNSClass]; } } OFString * OFDNSRecordTypeName(OFDNSRecordType recordType) { switch (recordType) { case OFDNSRecordTypeA: return @"A"; case OFDNSRecordTypeNS: return @"NS"; case OFDNSRecordTypeCNAME: return @"CNAME"; case OFDNSRecordTypeSOA: return @"SOA"; case OFDNSRecordTypePTR: return @"PTR"; case OFDNSRecordTypeHINFO: return @"HINFO"; case OFDNSRecordTypeMX: return @"MX"; case OFDNSRecordTypeTXT: return @"TXT"; case OFDNSRecordTypeRP: return @"RP"; case OFDNSRecordTypeAAAA: return @"AAAA"; case OFDNSRecordTypeSRV: return @"SRV"; case OFDNSRecordTypeAll: return @"all"; default: return [OFString stringWithFormat: @"%u", recordType]; } } OFDNSClass OFDNSClassParseName(OFString *string) { void *pool = objc_autoreleasePoolPush(); OFDNSClass DNSClass; string = string.uppercaseString; if ([string isEqual: @"IN"]) DNSClass = OFDNSClassIN; else { @try { DNSClass = (OFDNSClass) [string unsignedLongLongValueWithBase: 0]; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidArgumentException exception]; } } objc_autoreleasePoolPop(pool); return DNSClass; } OFDNSRecordType OFDNSRecordTypeParseName(OFString *string) { void *pool = objc_autoreleasePoolPush(); OFDNSRecordType recordType; string = string.uppercaseString; if ([string isEqual: @"A"]) recordType = OFDNSRecordTypeA; else if ([string isEqual: @"NS"]) recordType = OFDNSRecordTypeNS; else if ([string isEqual: @"CNAME"]) recordType = OFDNSRecordTypeCNAME; else if ([string isEqual: @"SOA"]) recordType = OFDNSRecordTypeSOA; else if ([string isEqual: @"PTR"]) recordType = OFDNSRecordTypePTR; else if ([string isEqual: @"HINFO"]) recordType = OFDNSRecordTypeHINFO; else if ([string isEqual: @"MX"]) recordType = OFDNSRecordTypeMX; else if ([string isEqual: @"TXT"]) recordType = OFDNSRecordTypeTXT; else if ([string isEqual: @"RP"]) recordType = OFDNSRecordTypeRP; else if ([string isEqual: @"AAAA"]) recordType = OFDNSRecordTypeAAAA; else if ([string isEqual: @"SRV"]) recordType = OFDNSRecordTypeSRV; else if ([string isEqual: @"ALL"]) recordType = OFDNSRecordTypeAll; else { @try { recordType = (OFDNSRecordType) [string unsignedLongLongValueWithBase: 0]; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidArgumentException exception]; } } objc_autoreleasePoolPop(pool); return recordType; } @implementation OFDNSResourceRecord @synthesize name = _name, DNSClass = _DNSClass, recordType = _recordType; @synthesize TTL = _TTL; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { self = [super init]; @try { _name = [name copy]; _DNSClass = DNSClass; |
︙ | ︙ | |||
179 180 181 182 183 184 185 | return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tType = %@\n" @"\tTTL = %" PRIu32 "\n" @">", | | | | | | | | | | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tType = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, OFDNSClassName(_DNSClass), OFDNSRecordTypeName(_recordType), _TTL]; } @end @implementation OFADNSResourceRecord - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name address: (const OFSocketAddress *)address TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: OFDNSClassIN recordType: OFDNSRecordTypeA TTL: TTL]; _address = *address; return self; } - (const OFSocketAddress *)address { return &_address; } - (bool)isEqual: (id)object { OFADNSResourceRecord *record; |
︙ | ︙ | |||
233 234 235 236 237 238 239 | if (record->_DNSClass != _DNSClass) return false; if (record->_recordType != _recordType) return false; | | | | | | | | | | | | < | | | | | | | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | if (record->_DNSClass != _DNSClass) return false; if (record->_recordType != _recordType) return false; if (!OFSocketAddressEqual(&record->_address, &_address)) return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAdd(&hash, _DNSClass >> 8); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType >> 8); OFHashAdd(&hash, _recordType); OFHashAddHash(&hash, OFSocketAddressHash(&_address)); OFHashFinalize(&hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tAddress = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, OFSocketAddressString(&_address), _TTL]; } @end @implementation OFAAAADNSResourceRecord - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name address: (const OFSocketAddress *)address TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: OFDNSClassIN recordType: OFDNSRecordTypeAAAA TTL: TTL]; _address = *address; return self; } - (const OFSocketAddress *)address { return &_address; } - (bool)isEqual: (id)object { OFAAAADNSResourceRecord *record; |
︙ | ︙ | |||
319 320 321 322 323 324 325 | if (record->_DNSClass != _DNSClass) return false; if (record->_recordType != _recordType) return false; | | | | | | | | | | | | < | | | | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | if (record->_DNSClass != _DNSClass) return false; if (record->_recordType != _recordType) return false; if (!OFSocketAddressEqual(&record->_address, &_address)) return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAdd(&hash, _DNSClass >> 8); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType >> 8); OFHashAdd(&hash, _recordType); OFHashAddHash(&hash, OFSocketAddressHash(&_address)); OFHashFinalize(&hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tAddress = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, OFSocketAddressString(&_address), _TTL]; } @end @implementation OFCNAMEDNSResourceRecord @synthesize alias = _alias; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass alias: (OFString *)alias TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: DNSClass recordType: OFDNSRecordTypeCNAME TTL: TTL]; @try { _alias = [alias copy]; } @catch (id e) { [self release]; @throw e; |
︙ | ︙ | |||
423 424 425 426 427 428 429 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | < | | | | | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAdd(&hash, _DNSClass >> 8); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType >> 8); OFHashAdd(&hash, _recordType); OFHashAddHash(&hash, _alias.hash); OFHashFinalize(&hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tAlias = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, OFDNSClassName(_DNSClass), _alias, _TTL]; } @end @implementation OFHINFODNSResourceRecord @synthesize CPU = _CPU, OS = _OS; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass CPU: (OFString *)CPU OS: (OFString *)OS TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: DNSClass recordType: OFDNSRecordTypeHINFO TTL: TTL]; @try { _CPU = [CPU copy]; _OS = [OS copy]; } @catch (id e) { [self release]; |
︙ | ︙ | |||
526 527 528 529 530 531 532 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | | < | | | | | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAdd(&hash, _DNSClass >> 8); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType >> 8); OFHashAdd(&hash, _recordType); OFHashAddHash(&hash, _CPU.hash); OFHashAddHash(&hash, _OS.hash); OFHashFinalize(&hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tCPU = %@\n" @"\tOS = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, OFDNSClassName(_DNSClass), _CPU, _OS, _TTL]; } @end @implementation OFMXDNSResourceRecord @synthesize preference = _preference, mailExchange = _mailExchange; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass preference: (uint16_t)preference mailExchange: (OFString *)mailExchange TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: DNSClass recordType: OFDNSRecordTypeMX TTL: TTL]; @try { _preference = preference; _mailExchange = [mailExchange copy]; } @catch (id e) { [self release]; |
︙ | ︙ | |||
631 632 633 634 635 636 637 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | | | | | | | | | 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAdd(&hash, _DNSClass >> 8); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType >> 8); OFHashAdd(&hash, _recordType); OFHashAdd(&hash, _preference >> 8); OFHashAdd(&hash, _preference); OFHashAddHash(&hash, _mailExchange.hash); OFHashFinalize(&hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tPreference = %" PRIu16 "\n" @"\tMail Exchange = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, OFDNSClassName(_DNSClass), _preference, _mailExchange, _TTL]; } @end @implementation OFNSDNSResourceRecord @synthesize authoritativeHost = _authoritativeHost; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass authoritativeHost: (OFString *)authoritativeHost TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: DNSClass recordType: OFDNSRecordTypeNS TTL: TTL]; @try { _authoritativeHost = [authoritativeHost copy]; } @catch (id e) { [self release]; @throw e; |
︙ | ︙ | |||
732 733 734 735 736 737 738 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | | | | | | 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAdd(&hash, _DNSClass >> 8); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType >> 8); OFHashAdd(&hash, _recordType); OFHashAddHash(&hash, _authoritativeHost.hash); OFHashFinalize(&hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tAuthoritative Host = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, OFDNSClassName(_DNSClass), _authoritativeHost, _TTL]; } @end @implementation OFPTRDNSResourceRecord @synthesize domainName = _domainName; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass domainName: (OFString *)domainName TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: DNSClass recordType: OFDNSRecordTypePTR TTL: TTL]; @try { _domainName = [domainName copy]; } @catch (id e) { [self release]; @throw e; |
︙ | ︙ | |||
830 831 832 833 834 835 836 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | | | | | | | 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAdd(&hash, _DNSClass >> 8); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType >> 8); OFHashAdd(&hash, _recordType); OFHashAddHash(&hash, _domainName.hash); OFHashFinalize(&hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tDomain Name = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, OFDNSClassName(_DNSClass), _domainName, _TTL]; } @end @implementation OFRPDNSResourceRecord @synthesize mailbox = _mailbox, TXTDomainName = _TXTDomainName; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass mailbox: (OFString *)mailbox TXTDomainName: (OFString *)TXTDomainName TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: DNSClass recordType: OFDNSRecordTypeRP TTL: TTL]; @try { _mailbox = [mailbox copy]; _TXTDomainName = [TXTDomainName copy]; } @catch (id e) { [self release]; |
︙ | ︙ | |||
935 936 937 938 939 940 941 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | | | | | | | 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAdd(&hash, _DNSClass >> 8); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType >> 8); OFHashAdd(&hash, _recordType); OFHashAddHash(&hash, _mailbox.hash); OFHashAddHash(&hash, _TXTDomainName.hash); OFHashFinalize(&hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tMailbox = %@\n" @"\tTXT Domain Name = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, OFDNSClassName(_DNSClass), _mailbox, _TXTDomainName, _TTL]; } @end @implementation OFSOADNSResourceRecord @synthesize primaryNameServer = _primaryNameServer; @synthesize responsiblePerson = _responsiblePerson; @synthesize serialNumber = _serialNumber, refreshInterval = _refreshInterval; @synthesize retryInterval = _retryInterval; @synthesize expirationInterval = _expirationInterval, minTTL = _minTTL; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass primaryNameServer: (OFString *)primaryNameServer responsiblePerson: (OFString *)responsiblePerson serialNumber: (uint32_t)serialNumber refreshInterval: (uint32_t)refreshInterval retryInterval: (uint32_t)retryInterval expirationInterval: (uint32_t)expirationInterval minTTL: (uint32_t)minTTL TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: DNSClass recordType: OFDNSRecordTypeSOA TTL: TTL]; @try { _primaryNameServer = [primaryNameServer copy]; _responsiblePerson = [responsiblePerson copy]; _serialNumber = serialNumber; _refreshInterval = refreshInterval; |
︙ | ︙ | |||
1071 1072 1073 1074 1075 1076 1077 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAdd(&hash, _DNSClass >> 8); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType >> 8); OFHashAdd(&hash, _recordType); OFHashAddHash(&hash, _primaryNameServer.hash); OFHashAddHash(&hash, _responsiblePerson.hash); OFHashAdd(&hash, _serialNumber >> 24); OFHashAdd(&hash, _serialNumber >> 16); OFHashAdd(&hash, _serialNumber >> 8); OFHashAdd(&hash, _serialNumber); OFHashAdd(&hash, _refreshInterval >> 24); OFHashAdd(&hash, _refreshInterval >> 16); OFHashAdd(&hash, _refreshInterval >> 8); OFHashAdd(&hash, _refreshInterval); OFHashAdd(&hash, _retryInterval >> 24); OFHashAdd(&hash, _retryInterval >> 16); OFHashAdd(&hash, _retryInterval >> 8); OFHashAdd(&hash, _retryInterval); OFHashAdd(&hash, _expirationInterval >> 24); OFHashAdd(&hash, _expirationInterval >> 16); OFHashAdd(&hash, _expirationInterval >> 8); OFHashAdd(&hash, _expirationInterval); OFHashAdd(&hash, _minTTL >> 24); OFHashAdd(&hash, _minTTL >> 16); OFHashAdd(&hash, _minTTL >> 8); OFHashAdd(&hash, _minTTL); OFHashFinalize(&hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tPrimary Name Server = %@\n" @"\tResponsible Person = %@\n" @"\tSerial Number = %" PRIu32 "\n" @"\tRefresh Interval = %" PRIu32 "\n" @"\tRetry Interval = %" PRIu32 "\n" @"\tExpiration Interval = %" PRIu32 "\n" @"\tMinimum TTL = %" PRIu32 "\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, OFDNSClassName(_DNSClass), _primaryNameServer, _responsiblePerson, _serialNumber, _refreshInterval, _retryInterval, _expirationInterval, _minTTL, _TTL]; } @end @implementation OFSRVDNSResourceRecord @synthesize priority = _priority, weight = _weight, target = _target; @synthesize port = _port; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name priority: (uint16_t)priority weight: (uint16_t)weight target: (OFString *)target port: (uint16_t)port TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: OFDNSClassIN recordType: OFDNSRecordTypeSRV TTL: TTL]; @try { _priority = priority; _weight = weight; _target = [target copy]; _port = port; |
︙ | ︙ | |||
1212 1213 1214 1215 1216 1217 1218 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | | | | | | | 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAdd(&hash, _DNSClass >> 8); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType >> 8); OFHashAdd(&hash, _recordType); OFHashAdd(&hash, _priority >> 8); OFHashAdd(&hash, _priority); OFHashAdd(&hash, _weight >> 8); OFHashAdd(&hash, _weight); OFHashAddHash(&hash, _target.hash); OFHashAdd(&hash, _port >> 8); OFHashAdd(&hash, _port); OFHashFinalize(&hash); return hash; } - (OFString *)description { return [OFString stringWithFormat: |
︙ | ︙ | |||
1253 1254 1255 1256 1257 1258 1259 | } @end @implementation OFTXTDNSResourceRecord @synthesize textStrings = _textStrings; - (instancetype)initWithName: (OFString *)name | | | | | | 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 | } @end @implementation OFTXTDNSResourceRecord @synthesize textStrings = _textStrings; - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass recordType: (OFDNSRecordType)recordType TTL: (uint32_t)TTL { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name DNSClass: (OFDNSClass)DNSClass textStrings: (OFArray OF_GENERIC(OFData *) *)textStrings TTL: (uint32_t)TTL { self = [super initWithName: name DNSClass: DNSClass recordType: OFDNSRecordTypeTXT TTL: TTL]; @try { _textStrings = [textStrings copy]; } @catch (id e) { [self release]; @throw e; |
︙ | ︙ | |||
1317 1318 1319 1320 1321 1322 1323 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAdd(&hash, _DNSClass >> 8); OFHashAdd(&hash, _DNSClass); OFHashAdd(&hash, _recordType >> 8); OFHashAdd(&hash, _recordType); OFHashAddHash(&hash, _textStrings.hash); OFHashFinalize(&hash); return hash; } - (OFString *)description { void *pool = objc_autoreleasePoolPush(); |
︙ | ︙ | |||
1373 1374 1375 1376 1377 1378 1379 | ret = [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tText strings = %@\n" @"\tTTL = %" PRIu32 "\n" @">", | | < | 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 | ret = [OFString stringWithFormat: @"<%@:\n" @"\tName = %@\n" @"\tClass = %@\n" @"\tText strings = %@\n" @"\tTTL = %" PRIu32 "\n" @">", self.className, _name, OFDNSClassName(_DNSClass), text, _TTL]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end |
Modified src/OFDNSResponse.h from [49ce9c1af3] to [12d5300b31].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFDictionary OF_GENERIC(KeyType, ObjectType); typedef OFDictionary OF_GENERIC(OFString *, OFArray OF_GENERIC( | | < | | | | | < | | | | < | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFDictionary OF_GENERIC(KeyType, ObjectType); typedef OFDictionary OF_GENERIC(OFString *, OFArray OF_GENERIC( OF_KINDOF(OFDNSResourceRecord *)) *) *OFDNSResponseRecords; /** * @class OFDNSResponse OFDNSResponse.h ObjFW/OFDNSResponse.h * * @brief A class storing a response from @ref OFDNSResolver. */ @interface OFDNSResponse: OFObject { OFString *_domainName; OFDNSResponseRecords _answerRecords, _authorityRecords; OFDNSResponseRecords _additionalRecords; OF_RESERVE_IVARS(OFDNSResponse, 4) } /** * @brief The domain name of the response. */ @property (readonly, nonatomic) OFString *domainName; /** * @brief The answer records of the response. * * This is a dictionary with the key being the domain name and the value being * an array of @ref OFDNSResourceRecord. */ @property (readonly, nonatomic) OFDNSResponseRecords answerRecords; /** * @brief The authority records of the response. * * This is a dictionary with the key being the domain name and the value being * an array of @ref OFDNSResourceRecord. */ @property (readonly, nonatomic) OFDNSResponseRecords authorityRecords; /** * @brief The additional records of the response. * * This is a dictionary with the key being the domain name and the value being * an array of @ref OFDNSResourceRecord. */ @property (readonly, nonatomic) OFDNSResponseRecords additionalRecords; /** * @brief Creates a new, autoreleased OFDNSResponse. * * @param domainName The domain name the response is for * @param answerRecords The answer records of the response * @param authorityRecords The authority records of the response * @param additionalRecords The additional records of the response * @return A new, autoreleased OFDNSResponse */ + (instancetype)responseWithDomainName: (OFString *)domainName answerRecords: (OFDNSResponseRecords)answerRecords authorityRecords: (OFDNSResponseRecords)authorityRecords additionalRecords: (OFDNSResponseRecords)additionalRecords; /** * @brief Initializes an already allocated OFDNSResponse. * * @param domainName The domain name the response is for * @param answerRecords The answer records of the response * @param authorityRecords The authority records of the response * @param additionalRecords The additional records of the response * @return An initialized OFDNSResponse */ - (instancetype)initWithDomainName: (OFString *)domainName answerRecords: (OFDNSResponseRecords)answerRecords authorityRecords: (OFDNSResponseRecords)authorityRecords additionalRecords: (OFDNSResponseRecords)additionalRecords OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/OFDNSResponse.m from [f58f953bdc] to [6e61ece6f0].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | #import "OFString.h" @implementation OFDNSResponse @synthesize domainName = _domainName, answerRecords = _answerRecords; @synthesize authorityRecords = _authorityRecords; @synthesize additionalRecords = _additionalRecords; | < | | | | | | | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #import "OFString.h" @implementation OFDNSResponse @synthesize domainName = _domainName, answerRecords = _answerRecords; @synthesize authorityRecords = _authorityRecords; @synthesize additionalRecords = _additionalRecords; + (instancetype)responseWithDomainName: (OFString *)domainName answerRecords: (OFDNSResponseRecords)answerRecords authorityRecords: (OFDNSResponseRecords)authorityRecords additionalRecords: (OFDNSResponseRecords)additionalRecords { return [[[self alloc] initWithDomainName: domainName answerRecords: answerRecords authorityRecords: authorityRecords additionalRecords: additionalRecords] autorelease]; } - (instancetype)initWithDomainName: (OFString *)domainName answerRecords: (OFDNSResponseRecords)answerRecords authorityRecords: (OFDNSResponseRecords)authorityRecords additionalRecords: (OFDNSResponseRecords)additionalRecords { self = [super init]; @try { _domainName = [domainName copy]; _answerRecords = [answerRecords copy]; _authorityRecords = [authorityRecords copy]; _additionalRecords = [additionalRecords copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_domainName release]; |
︙ | ︙ | |||
100 101 102 103 104 105 106 | return false; return true; } - (unsigned long)hash { | | | | | | | | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _domainName.hash); OFHashAddHash(&hash, [_answerRecords hash]); OFHashAddHash(&hash, [_authorityRecords hash]); OFHashAddHash(&hash, [_additionalRecords hash]); OFHashFinalize(&hash); return hash; } - (OFString *)description { OFString *answerRecords = [_answerRecords.description |
︙ | ︙ |
Deleted src/OFData+ASN1DERParsing.h version [7ece1a8d4e].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFData+ASN1DERParsing.m version [31638813f3].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Renamed and modified src/OFData+CryptoHashing.h [c36da9d392] to src/OFData+CryptographicHashing.h [7264dfad2c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | OF_ASSUME_NONNULL_BEGIN @class OFString; #ifdef __cplusplus extern "C" { #endif | | | | | | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | OF_ASSUME_NONNULL_BEGIN @class OFString; #ifdef __cplusplus extern "C" { #endif extern int _OFData_CryptographicHashing_reference; #ifdef __cplusplus } #endif @interface OFData (CryptographicHashing) /** * @brief The MD5 hash of the data as a string. */ @property (readonly, nonatomic) OFString *stringByMD5Hashing; /** * @brief The RIPEMD-160 hash of the data as a string. */ @property (readonly, nonatomic) OFString *stringByRIPEMD160Hashing; /** * @brief The SHA-1 hash of the data as a string. */ @property (readonly, nonatomic) OFString *stringBySHA1Hashing; /** * @brief The SHA-224 hash of the data as a string. */ @property (readonly, nonatomic) OFString *stringBySHA224Hashing; /** * @brief The SHA-256 hash of the data as a string. */ @property (readonly, nonatomic) OFString *stringBySHA256Hashing; /** * @brief The SHA-384 hash of the data as a string. */ @property (readonly, nonatomic) OFString *stringBySHA384Hashing; /** * @brief The SHA-512 hash of the data as a string. */ @property (readonly, nonatomic) OFString *stringBySHA512Hashing; @end OF_ASSUME_NONNULL_END |
Renamed and modified src/OFData+CryptoHashing.m [7fbcd74f01] to src/OFData+CryptographicHashing.m [caf70aabc2].
1 | /* | < < | | | | | > | | | | | > | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFData+CryptographicHashing.h" #import "OFString.h" #import "OFCryptographicHash.h" #import "OFMD5Hash.h" #import "OFRIPEMD160Hash.h" #import "OFSHA1Hash.h" #import "OFSHA224Hash.h" #import "OFSHA256Hash.h" #import "OFSHA384Hash.h" #import "OFSHA512Hash.h" int _OFData_CryptographicHashing_reference; @implementation OFData (CryptographicHashing) static OFString * stringByHashing(Class <OFCryptographicHash> class, OFData *self) { void *pool = objc_autoreleasePoolPush(); id <OFCryptographicHash> hash = [class hashWithAllowsSwappableMemory: true]; size_t digestSize = [class digestSize]; 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; high = digest[i] >> 4; low = digest[i] & 0x0F; cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0'); cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0'); } objc_autoreleasePoolPop(pool); return [OFString stringWithCString: cString encoding: OFStringEncodingASCII length: digestSize * 2]; } - (OFString *)stringByMD5Hashing { return stringByHashing([OFMD5Hash class], self); } - (OFString *)stringByRIPEMD160Hashing { return stringByHashing([OFRIPEMD160Hash class], self); } - (OFString *)stringBySHA1Hashing { return stringByHashing([OFSHA1Hash class], self); } - (OFString *)stringBySHA224Hashing { return stringByHashing([OFSHA224Hash class], self); } - (OFString *)stringBySHA256Hashing { return stringByHashing([OFSHA256Hash class], self); } - (OFString *)stringBySHA384Hashing { return stringByHashing([OFSHA384Hash class], self); } - (OFString *)stringBySHA512Hashing { return stringByHashing([OFSHA512Hash class], self); } @end |
Modified src/OFData+MessagePackParsing.h from [174add13df] to [38e581e80e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFData+MessagePackParsing.m from [464ca7dfaa] to [8bd7ef8227].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
116 117 118 119 120 121 122 | pool = objc_autoreleasePoolPush(); pos += parseObject(buffer + pos, length - pos, &key, depthLimit); pos += parseObject(buffer + pos, length - pos, &value, depthLimit); | | < | | | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | pool = objc_autoreleasePoolPush(); pos += parseObject(buffer + pos, length - pos, &key, depthLimit); pos += parseObject(buffer + pos, length - pos, &value, depthLimit); [*object setObject: value forKey: key]; objc_autoreleasePoolPop(pool); } return pos; } static OFDate * createDate(OFData *data) { switch (data.count) { case 4: { uint32_t timestamp; memcpy(×tamp, data.items, 4); timestamp = OFFromBigEndian32(timestamp); return [OFDate dateWithTimeIntervalSince1970: timestamp]; } case 8: { uint64_t combined; memcpy(&combined, data.items, 8); combined = OFFromBigEndian64(combined); return [OFDate dateWithTimeIntervalSince1970: (double)(combined & 0x3FFFFFFFF) + (double)(combined >> 34) / 1000000000]; } case 12: { uint32_t nanoseconds; int64_t seconds; memcpy(&nanoseconds, data.items, 4); memcpy(&seconds, (char *)data.items + 4, 8); nanoseconds = OFFromBigEndian32(nanoseconds); seconds = OFFromBigEndian64(seconds); return [OFDate dateWithTimeIntervalSince1970: (double)seconds + (double)nanoseconds / 1000000000]; } default: @throw [OFInvalidFormatException exception]; } |
︙ | ︙ | |||
286 287 288 289 290 291 292 | float f; if (length < 5) @throw [OFTruncatedDataException exception]; memcpy(&f, buffer + 1, 4); | | | | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | float f; if (length < 5) @throw [OFTruncatedDataException exception]; memcpy(&f, buffer + 1, 4); *object = [OFNumber numberWithFloat: OFFromBigEndianFloat(f)]; return 5; case 0xCB:; /* float 64 */ double d; if (length < 9) @throw [OFTruncatedDataException exception]; memcpy(&d, buffer + 1, 8); *object = [OFNumber numberWithDouble: OFFromBigEndianDouble(d)]; return 9; /* nil */ case 0xC0: *object = [OFNull null]; return 1; /* false */ case 0xC2: |
︙ | ︙ | |||
320 321 322 323 324 325 326 | @throw [OFTruncatedDataException exception]; count = buffer[1]; if (length < count + 2) @throw [OFTruncatedDataException exception]; | | < | < | < | < | < | < | < | < | < | < | < | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | @throw [OFTruncatedDataException exception]; count = buffer[1]; if (length < count + 2) @throw [OFTruncatedDataException exception]; *object = [OFData dataWithItems: buffer + 2 count: count]; return count + 2; case 0xC5: /* bin 16 */ if (length < 3) @throw [OFTruncatedDataException exception]; count = readUInt16(buffer + 1); if (length < count + 3) @throw [OFTruncatedDataException exception]; *object = [OFData dataWithItems: buffer + 3 count: count]; return count + 3; case 0xC6: /* bin 32 */ if (length < 5) @throw [OFTruncatedDataException exception]; count = readUInt32(buffer + 1); if (length < count + 5) @throw [OFTruncatedDataException exception]; *object = [OFData dataWithItems: buffer + 5 count: count]; return count + 5; /* Extensions */ case 0xC7: /* ext 8 */ if (length < 3) @throw [OFTruncatedDataException exception]; count = buffer[1]; if (length < count + 3) @throw [OFTruncatedDataException exception]; data = [[OFData alloc] initWithItems: buffer + 3 count: count]; @try { *object = createExtension(buffer[2], data); } @finally { [data release]; } return count + 3; case 0xC8: /* ext 16 */ if (length < 4) @throw [OFTruncatedDataException exception]; count = readUInt16(buffer + 1); if (length < count + 4) @throw [OFTruncatedDataException exception]; data = [[OFData alloc] initWithItems: buffer + 4 count: count]; @try { *object = createExtension(buffer[3], data); } @finally { [data release]; } return count + 4; case 0xC9: /* ext 32 */ if (length < 6) @throw [OFTruncatedDataException exception]; count = readUInt32(buffer + 1); if (length < count + 6) @throw [OFTruncatedDataException exception]; data = [[OFData alloc] initWithItems: buffer + 6 count: count]; @try { *object = createExtension(buffer[5], data); } @finally { [data release]; } return count + 6; case 0xD4: /* fixext 1 */ if (length < 3) @throw [OFTruncatedDataException exception]; data = [[OFData alloc] initWithItems: buffer + 2 count: 1]; @try { *object = createExtension(buffer[1], data); } @finally { [data release]; } return 3; case 0xD5: /* fixext 2 */ if (length < 4) @throw [OFTruncatedDataException exception]; data = [[OFData alloc] initWithItems: buffer + 2 count: 2]; @try { *object = createExtension(buffer[1], data); } @finally { [data release]; } return 4; case 0xD6: /* fixext 4 */ if (length < 6) @throw [OFTruncatedDataException exception]; data = [[OFData alloc] initWithItems: buffer + 2 count: 4]; @try { *object = createExtension(buffer[1], data); } @finally { [data release]; } return 6; case 0xD7: /* fixext 8 */ if (length < 10) @throw [OFTruncatedDataException exception]; data = [[OFData alloc] initWithItems: buffer + 2 count: 8]; @try { *object = createExtension(buffer[1], data); } @finally { [data release]; } return 10; case 0xD8: /* fixext 16 */ if (length < 18) @throw [OFTruncatedDataException exception]; data = [[OFData alloc] initWithItems: buffer + 2 count: 16]; @try { *object = createExtension(buffer[1], data); } @finally { [data release]; } return 18; |
︙ | ︙ |
Modified src/OFData.h from [bbb0884145] to [858a27b08c].
1 | /* | < < | > > > > > > > | > | < > | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFSerialization.h" #import "OFMessagePackRepresentation.h" /*! @file */ OF_ASSUME_NONNULL_BEGIN @class OFString; @class OFURL; /** * @brief Options for searching in data. * * This is a bit mask. */ typedef enum { /** Search backwards in the data */ OFDataSearchBackwards = 1 } OFDataSearchOptions; /** * @class OFData OFData.h ObjFW/OFData.h * * @brief A class for storing arbitrary data in an array. * * For security reasons, serialization and deserialization is only implemented * for OFData with item size 1. */ @interface OFData: OFObject <OFCopying, OFMutableCopying, OFComparing, OFSerialization, OFMessagePackRepresentation> { unsigned char *_Nullable _items; size_t _count, _itemSize; bool _freeWhenDone; @private OFData *_Nullable _parentData; OF_RESERVE_IVARS(OFData, 4) } /** * @brief The size of a single item in the OFData in bytes. */ @property (readonly, nonatomic) size_t itemSize; /** * @brief The number of items in the OFData. */ @property (readonly, nonatomic) size_t count; /** * @brief All elements of the OFData as a C array. * * @warning The pointer is only valid until the OFData is changed! */ @property 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 OF_RETURNS_INNER_POINTER; |
︙ | ︙ | |||
92 93 94 95 96 97 98 | /** * @brief Creates a new OFData with the specified `count` items of size 1. * * @param items The items to store in the OFData * @param count The number of items * @return A new autoreleased OFData */ | | < < > < | > > > > > > > < > < > | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | /** * @brief Creates a new OFData with the specified `count` items of size 1. * * @param items The items to store in the OFData * @param count The number of items * @return A new autoreleased OFData */ + (instancetype)dataWithItems: (const void *)items count: (size_t)count; /** * @brief Creates a new OFData with the specified `count` items of the * specified size. * * @param items The items to store in the OFData * @param count The number of items * @param itemSize The item size of a single item in bytes * @return A new autoreleased OFData */ + (instancetype)dataWithItems: (const void *)items count: (size_t)count itemSize: (size_t)itemSize; /** * @brief Creates a new OFData with the specified `count` items of size 1 by * taking over ownership of the specified items pointer. * * If initialization fails for whatever reason, the passed memory is *not* * free'd if `freeWhenDone` is true. * * @param items The items to store in the OFData * @param count The number of items * @param freeWhenDone Whether to free the pointer when it is no longer needed * by the OFData * @return A new autoreleased OFData */ + (instancetype)dataWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone; /** * @brief Creates a new OFData with the specified `count` items of the * specified size by taking ownership of the specified items pointer. * * If initialization fails for whatever reason, the passed memory is *not* * free'd if `freeWhenDone` is true. * * @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 * @param freeWhenDone Whether to free the pointer when it is no longer needed * by the OFData * @return A new autoreleased OFData */ + (instancetype)dataWithItemsNoCopy: (void *)items count: (size_t)count itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone; #ifdef OF_HAVE_FILES /** * @brief Creates a new OFData with an item size of 1, containing the data of * the specified file. * |
︙ | ︙ | |||
160 161 162 163 164 165 166 | * @param URL The URL to the contents for the OFData * @return A new autoreleased OFData */ + (instancetype)dataWithContentsOfURL: (OFURL *)URL; /** * @brief Creates a new OFData with an item size of 1, containing the data of | | | | | < | < > < | > > > > > > > < > < > | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | * @param URL The URL to the contents for the OFData * @return A new autoreleased OFData */ + (instancetype)dataWithContentsOfURL: (OFURL *)URL; /** * @brief Creates a new OFData with an item size of 1, containing the data of * the hex string representation. * * @param string The hex string representation of the data * @return A new autoreleased OFData */ + (instancetype)dataWithStringRepresentation: (OFString *)string; /** * @brief Creates a new OFData with an item size of 1, containing the data of * the Base64-encoded string. * * @param string The string with the Base64-encoded data * @return A new autoreleased OFData */ + (instancetype)dataWithBase64EncodedString: (OFString *)string; /** * @brief 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 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 * @return An initialized OFData */ - (instancetype)initWithItems: (const void *)items count: (size_t)count itemSize: (size_t)itemSize; /** * @brief Initializes an already allocated OFData with the specified `count` * items of size 1 by taking over ownership of the specified items * pointer. * * If initialization fails for whatever reason, the passed memory is *not* * free'd if `freeWhenDone` is true. * * @param items The items to store in the OFData * @param count The number of items * @param freeWhenDone Whether to free the pointer when it is no longer needed * by the OFData * @return An initialized OFData */ - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone; /** * @brief Initializes an already allocated OFData with the specified `count` * items of the specified size by taking ownership of the specified * items pointer. * * If initialization fails for whatever reason, the passed memory is *not* * free'd if `freeWhenDone` is true. * * @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 * @param freeWhenDone Whether to free the pointer when it is no longer needed * by the OFData * @return An initialized OFData */ - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone; #ifdef OF_HAVE_FILES /** * @brief Initializes an already allocated OFData with an item size of 1, * containing the data of the specified file. * |
︙ | ︙ | |||
254 255 256 257 258 259 260 | * @param URL The URL to the contents for the OFData * @return A new autoreleased OFData */ - (instancetype)initWithContentsOfURL: (OFURL *)URL; /** * @brief Initializes an already allocated OFData with an item size of 1, | | | > > > > > > > > | | < < < < | | | | | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | * @param URL The URL to the contents for the OFData * @return A new autoreleased OFData */ - (instancetype)initWithContentsOfURL: (OFURL *)URL; /** * @brief Initializes an already allocated OFData with an item size of 1, * containing the data of the hex string representation. * * @param string The hex string representation of the data * @return A new autoreleased OFData */ - (instancetype)initWithStringRepresentation: (OFString *)string; /** * @brief Initializes an already allocated OFData with an item size of 1, * containing the data of the Base64-encoded string. * * @param string The string with the Base64-encoded data * @return An initialized OFData */ - (instancetype)initWithBase64EncodedString: (OFString *)string; /** * @brief Compares the data to other data. * * @param data Data to compare the data to * @return The result of the comparison */ - (OFComparisonResult)compare: (OFData *)data; /** * @brief Returns a specific item of the OFData. * * @param index The number of the item to return * @return The specified item of the OFData */ - (const void *)itemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER; /** * @brief Returns the data in the specified range as a new OFData. * * @param range The range of the data for the new OFData * @return The data in the specified range as a new OFData */ - (OFData *)subdataWithRange: (OFRange)range; /** * @brief Returns the range of the data. * * @param data The data to search for * @param options Options modifying search behavior * @param range The range in which to search * @return The range of the first occurrence of the data or a range with * `OFNotFound` as start position if it was not found. */ - (OFRange)rangeOfData: (OFData *)data options: (OFDataSearchOptions)options range: (OFRange)range; #ifdef OF_HAVE_FILES /** * @brief Writes the OFData into the specified file. * * @param path The path of the file to write to */ |
︙ | ︙ | |||
323 324 325 326 327 328 329 | */ - (void)writeToURL: (OFURL *)URL; @end OF_ASSUME_NONNULL_END #import "OFMutableData.h" | < | | 344 345 346 347 348 349 350 351 352 | */ - (void)writeToURL: (OFURL *)URL; @end OF_ASSUME_NONNULL_END #import "OFMutableData.h" #import "OFData+CryptographicHashing.h" #import "OFData+MessagePackParsing.h" |
Modified src/OFData.m from [bf7091f2d8] to [b6152aa57a].
1 | /* | < < | > < < < | | < | < < > > | < < > < > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdlib.h> #include <string.h> #include <limits.h> #import "OFData.h" #import "OFBase64.h" #import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFile.h" # import "OFFileManager.h" #endif #import "OFStream.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFURL.h" #import "OFURLHandler.h" #import "OFXMLElement.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" /* References for static linking */ void _references_to_categories_of_OFData(void) { _OFData_CryptographicHashing_reference = 1; _OFData_MessagePackParsing_reference = 1; } @implementation OFData @synthesize itemSize = _itemSize; + (instancetype)dataWithItems: (const void *)items count: (size_t)count { return [[[self alloc] initWithItems: items count: count] autorelease]; } + (instancetype)dataWithItems: (const void *)items count: (size_t)count itemSize: (size_t)itemSize { return [[[self alloc] initWithItems: items count: count itemSize: itemSize] autorelease]; } + (instancetype)dataWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone { return [[[self alloc] initWithItemsNoCopy: items count: count freeWhenDone: freeWhenDone] autorelease]; } + (instancetype)dataWithItemsNoCopy: (void *)items count: (size_t)count itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone { return [[[self alloc] initWithItemsNoCopy: items count: count itemSize: itemSize freeWhenDone: freeWhenDone] autorelease]; } #ifdef OF_HAVE_FILES + (instancetype)dataWithContentsOfFile: (OFString *)path { return [[[self alloc] initWithContentsOfFile: path] autorelease]; |
︙ | ︙ | |||
111 112 113 114 115 116 117 | } + (instancetype)dataWithBase64EncodedString: (OFString *)string { return [[[self alloc] initWithBase64EncodedString: string] autorelease]; } | | < | < < < > | | | < > < > < > | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | } + (instancetype)dataWithBase64EncodedString: (OFString *)string { return [[[self alloc] initWithBase64EncodedString: string] autorelease]; } - (instancetype)initWithItems: (const void *)items count: (size_t)count { return [self initWithItems: items count: count itemSize: 1]; } - (instancetype)initWithItems: (const void *)items count: (size_t)count itemSize: (size_t)itemSize { self = [super init]; @try { if (itemSize == 0) @throw [OFInvalidArgumentException exception]; _items = OFAllocMemory(count, itemSize); _count = count; _itemSize = itemSize; _freeWhenDone = true; memcpy(_items, items, count * itemSize); } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone { return [self initWithItemsNoCopy: items count: count itemSize: 1 freeWhenDone: freeWhenDone]; } - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone { self = [super init]; @try { if (itemSize == 0) @throw [OFInvalidArgumentException exception]; _items = (unsigned char *)items; _count = count; _itemSize = itemSize; _freeWhenDone = freeWhenDone; } @catch (id e) { [self release]; @throw e; } return self; |
︙ | ︙ | |||
193 194 195 196 197 198 199 | attributesOfItemAtPath: path].fileSize; # if ULLONG_MAX > SIZE_MAX if (size > SIZE_MAX) @throw [OFOutOfRangeException exception]; # endif | | | < | < | | | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | attributesOfItemAtPath: path].fileSize; # if ULLONG_MAX > SIZE_MAX if (size > SIZE_MAX) @throw [OFOutOfRangeException exception]; # endif buffer = OFAllocMemory((size_t)size, 1); file = [[OFFile alloc] initWithPath: path mode: @"r"]; @try { [file readIntoBuffer: buffer exactLength: (size_t)size]; } @finally { [file release]; } } @catch (id e) { OFFreeMemory(buffer); [self release]; @throw e; } @try { self = [self initWithItemsNoCopy: buffer count: (size_t)size freeWhenDone: true]; } @catch (id e) { OFFreeMemory(buffer); @throw e; } return self; } #endif |
︙ | ︙ | |||
237 238 239 240 241 242 243 | size_t pageSize; unsigned char *buffer; if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; | | < > | | > | | > | | | > | | | | > > > | | > | | < | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | size_t pageSize; unsigned char *buffer; if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; stream = [URLHandler openItemAtURL: URL mode: @"r"]; _count = 0; _itemSize = 1; _freeWhenDone = true; pageSize = [OFSystemInfo pageSize]; buffer = OFAllocMemory(1, pageSize); @try { while (!stream.atEndOfStream) { size_t length = [stream readIntoBuffer: buffer length: pageSize]; if (SIZE_MAX - _count < length) @throw [OFOutOfRangeException exception]; _items = OFResizeMemory(_items, _count + length, 1); memcpy(_items + _count, buffer, length); _count += length; } } @finally { OFFreeMemory(buffer); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithStringRepresentation: (OFString *)string { self = [super init]; @try { size_t count = [string cStringLengthWithEncoding: OFStringEncodingASCII]; const char *cString; if (count % 2 != 0) @throw [OFInvalidFormatException exception]; count /= 2; _items = OFAllocMemory(count, 1); _count = count; _itemSize = 1; _freeWhenDone = true; cString = [string cStringWithEncoding: OFStringEncodingASCII]; for (size_t i = 0; i < count; i++) { uint8_t c1 = cString[2 * i]; uint8_t c2 = cString[2 * i + 1]; uint8_t byte; if (c1 >= '0' && c1 <= '9') |
︙ | ︙ | |||
334 335 336 337 338 339 340 | [self release]; self = [OFMutableData alloc]; } self = [(OFMutableData *)self initWithCapacity: string.length / 3]; @try { | | | | < | | | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | [self release]; self = [OFMutableData alloc]; } self = [(OFMutableData *)self initWithCapacity: string.length / 3]; @try { if (!OFBase64Decode((OFMutableData *)self, [string cStringWithEncoding: OFStringEncodingASCII], [string cStringLengthWithEncoding: OFStringEncodingASCII])) @throw [OFInvalidFormatException exception]; } @catch (id e) { [self release]; @throw e; } if (!mutable) [(OFMutableData *)self makeImmutable]; return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { void *pool = objc_autoreleasePoolPush(); OFString *stringValue; @try { if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; stringValue = element.stringValue; } @catch (id e) { [self release]; @throw e; } self = [self initWithBase64EncodedString: stringValue]; objc_autoreleasePoolPop(pool); return self; } - (void)dealloc { if (_freeWhenDone) OFFreeMemory(_items); [_parentData release]; [super dealloc]; } - (size_t)count |
︙ | ︙ | |||
425 426 427 428 429 430 431 | { return [self retain]; } - (id)mutableCopy { return [[OFMutableData alloc] initWithItems: _items | > | < | 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | { return [self retain]; } - (id)mutableCopy { return [[OFMutableData alloc] initWithItems: _items count: _count itemSize: _itemSize]; } - (bool)isEqual: (id)object { OFData *data; if (object == self) |
︙ | ︙ | |||
449 450 451 452 453 454 455 | return false; if (memcmp(data.items, _items, _count * _itemSize) != 0) return false; return true; } | | < | < < | | | | | | | | | | < > | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 | return false; if (memcmp(data.items, _items, _count * _itemSize) != 0) return false; return true; } - (OFComparisonResult)compare: (OFData *)data { int comparison; size_t count, minCount; if (![data isKindOfClass: [OFData class]]) @throw [OFInvalidArgumentException exception]; if (data.itemSize != _itemSize) @throw [OFInvalidArgumentException exception]; count = data.count; minCount = (_count > count ? count : _count); if ((comparison = memcmp(_items, data.items, minCount * _itemSize)) == 0) { if (_count > count) return OFOrderedDescending; if (_count < count) return OFOrderedAscending; return OFOrderedSame; } if (comparison > 0) return OFOrderedDescending; else return OFOrderedAscending; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); for (size_t i = 0; i < _count * _itemSize; i++) OFHashAdd(&hash, ((uint8_t *)_items)[i]); OFHashFinalize(&hash); return hash; } - (OFData *)subdataWithRange: (OFRange)range { OFData *ret; if (range.length > SIZE_MAX - range.location || range.location + range.length > _count) @throw [OFOutOfRangeException exception]; ret = [OFData dataWithItemsNoCopy: _items + (range.location * _itemSize) count: range.length itemSize: _itemSize freeWhenDone: false]; ret->_parentData = [(_parentData != nil ? _parentData : self) copy]; return ret; } - (OFString *)description |
︙ | ︙ | |||
545 546 547 548 549 550 551 | [ret makeImmutable]; return ret; } - (OFString *)stringByBase64Encoding { | | | | | | | | | | | | < < | < < | < < | | | < < | | < < | < | | < < | < | < < | 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 | [ret makeImmutable]; return ret; } - (OFString *)stringByBase64Encoding { return OFBase64Encode(_items, _count * _itemSize); } - (OFRange)rangeOfData: (OFData *)data options: (OFDataSearchOptions)options range: (OFRange)range { const char *search; size_t searchLength; if (range.length > SIZE_MAX - range.location || range.location + range.length > _count) @throw [OFOutOfRangeException exception]; if (data == nil || data.itemSize != _itemSize) @throw [OFInvalidArgumentException exception]; if ((searchLength = data.count) == 0) return OFRangeMake(0, 0); if (searchLength > range.length) return OFRangeMake(OFNotFound, 0); search = data.items; if (options & OFDataSearchBackwards) { for (size_t i = range.length - searchLength;; i--) { if (memcmp(_items + i * _itemSize, search, searchLength * _itemSize) == 0) return OFRangeMake(i, searchLength); /* No match and we're at the last item */ if (i == 0) break; } } else { for (size_t i = range.location; i <= range.length - searchLength; i++) if (memcmp(_items + i * _itemSize, search, searchLength * _itemSize) == 0) return OFRangeMake(i, searchLength); } return OFRangeMake(OFNotFound, 0); } #ifdef OF_HAVE_FILES - (void)writeToFile: (OFString *)path { OFFile *file = [[OFFile alloc] initWithPath: path mode: @"w"]; @try { [file writeBuffer: _items length: _count * _itemSize]; } @finally { [file release]; } } #endif - (void)writeToURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); OFURLHandler *URLHandler; if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; [[URLHandler openItemAtURL: URL mode: @"w"] writeData: self]; objc_autoreleasePoolPop(pool); } - (OFXMLElement *)XMLElementBySerializing { void *pool; OFXMLElement *element; if (_itemSize != 1) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); element = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS stringValue: OFBase64Encode(_items, _count * _itemSize)]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } - (OFData *)messagePackRepresentation { OFMutableData *data; if (_itemSize != 1) @throw [OFInvalidArgumentException exception]; if (_count <= UINT8_MAX) { uint8_t type = 0xC4; uint8_t tmp = (uint8_t)_count; data = [OFMutableData dataWithCapacity: _count + 2]; [data addItem: &type]; [data addItem: &tmp]; } else if (_count <= UINT16_MAX) { uint8_t type = 0xC5; uint16_t tmp = OFToBigEndian16((uint16_t)_count); data = [OFMutableData dataWithCapacity: _count + 3]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (_count <= UINT32_MAX) { uint8_t type = 0xC6; uint32_t tmp = OFToBigEndian32((uint32_t)_count); data = [OFMutableData dataWithCapacity: _count + 5]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; [data addItems: _items count: _count]; [data makeImmutable]; return data; } @end |
Modified src/OFDatagramSocket.h from [d41735acda] to [c9d6b20376].
1 | /* | < < | < | | < | < < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFKernelEventObserver.h" #import "OFRunLoop.h" #import "OFSocket.h" OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFData; @class OFDatagramSocket; #ifdef OF_HAVE_BLOCKS /** * @brief A block which is called when a packet has been received. * * @param length The length of the packet * @param sender The address of the sender of the packet * @param exception An exception which occurred while receiving or `nil` on * success * @return A bool whether the same block should be used for the next receive */ typedef bool (^OFDatagramSocketAsyncReceiveBlock)(size_t length, const OFSocketAddress *_Nonnull sender, id _Nullable exception); /** * @brief A block which is called when a packet has been sent. * * @param exception An exception which occurred while reading or `nil` on * success * @return The data to repeat the send with or nil if it should not repeat */ typedef OFData *_Nullable (^OFDatagramSocketAsyncSendDataBlock)( id _Nullable exception); #endif /** * @protocol OFDatagramSocketDelegate OFDatagramSocket.h \ * ObjFW/OFDatagramSocket.h * |
︙ | ︙ | |||
74 75 76 77 78 79 80 | * @param exception An exception that occurred while receiving, or nil on * success * @return A bool whether the same block should be used for the next receive */ - (bool)socket: (OFDatagramSocket *)socket didReceiveIntoBuffer: (void *)buffer length: (size_t)length | | | | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | * @param exception An exception that occurred while receiving, or nil on * success * @return A bool whether the same block should be used for the next receive */ - (bool)socket: (OFDatagramSocket *)socket didReceiveIntoBuffer: (void *)buffer length: (size_t)length sender: (const OFSocketAddress *_Nonnull)sender exception: (nullable id)exception; /** * @brief This method is called when a packet has been sent. * * @param socket The datagram socket which sent a packet * @param data The data which was sent * @param receiver The receiver for the packet * @param exception An exception that occurred while sending, or nil on success * @return The data to repeat the send with or nil if it should not repeat */ - (nullable OFData *)socket: (OFDatagramSocket *)socket didSendData: (OFData *)data receiver: (const OFSocketAddress *_Nonnull)receiver exception: (nullable id)exception; @end /** * @class OFDatagramSocket OFDatagramSocket.h ObjFW/OFDatagramSocket.h * * @brief A base class for datagram sockets. * * @warning Even though the OFCopying protocol is implemented, it does *not* * return an independent copy of the socket, but instead retains it. * This is so that the socket can be used as a key for a dictionary, * so context can be associated with a socket. Using a socket in more * than one thread at the same time is not thread-safe, even if copy * was called to create one "instance" for every thread! */ @interface OFDatagramSocket: OFObject <OFCopying, OFReadyForReadingObserving, OFReadyForWritingObserving> { OFSocketHandle _socket; bool _canBlock; #ifdef OF_WII bool _canSendToBroadcastAddresses; #endif id <OFDatagramSocketDelegate> _Nullable _delegate; OF_RESERVE_IVARS(OFDatagramSocket, 4) } |
︙ | ︙ | |||
151 152 153 154 155 156 157 | /** * @brief Receives a datagram and stores it into the specified buffer. * * If the buffer is too small, the datagram is truncated. * * @param buffer The buffer to write the datagram to * @param length The length of the buffer | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | /** * @brief Receives a datagram and stores it into the specified buffer. * * If the buffer is too small, the datagram is truncated. * * @param buffer The buffer to write the datagram to * @param length The length of the buffer * @param sender A pointer to an @ref OFSocketAddress, which will be set to the * address of the sender * @return The length of the received datagram */ - (size_t)receiveIntoBuffer: (void *)buffer length: (size_t)length sender: (OFSocketAddress *)sender; /** * @brief Asynchronously receives a datagram and stores it into the specified * buffer. * * If the buffer is too small, the datagram is truncated. * * @param buffer The buffer to write the datagram to * @param length The length of the buffer */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length; /** * @brief Asynchronously receives a datagram and stores it into the specified * buffer. * * If the buffer is too small, the datagram is truncated. * * @param buffer The buffer to write the datagram to * @param length The length of the buffer * @param runLoopMode The run loop mode in which to perform the async receive */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode; #ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously receives a datagram and stores it into the specified * buffer. * * If the buffer is too small, the datagram is truncated. * * @param buffer The buffer to write the datagram to * @param length The length of the buffer * @param block The block to call when the datagram has been received. If the * block returns true, it will be called again with the same * buffer and maximum length when more datagrams have been * received. If you want the next method in the queue to handle * the datagram received next, you need to return false from the * method. */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length block: (OFDatagramSocketAsyncReceiveBlock)block; /** * @brief Asynchronously receives a datagram and stores it into the specified * buffer. * * If the buffer is too small, the datagram is truncated. * * @param buffer The buffer to write the datagram to * @param length The length of the buffer * @param runLoopMode The run loop mode in which to perform the async receive * @param block The block to call when the datagram has been received. If the * block returns true, it will be called again with the same * buffer and maximum length when more datagrams have been * received. If you want the next method in the queue to handle * the datagram received next, you need to return false from the * method. */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode block: (OFDatagramSocketAsyncReceiveBlock)block; #endif /** * @brief Sends the specified datagram to the specified address. * * @param buffer The buffer to send as a datagram * @param length The length of the buffer * @param receiver A pointer to an @ref OFSocketAddress to which the datagram * should be sent */ - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const OFSocketAddress *)receiver; /** * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref OFSocketAddress to which the datagram * should be sent. The receiver is copied. */ - (void)asyncSendData: (OFData *)data receiver: (const OFSocketAddress *)receiver; /** * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref OFSocketAddress to which the datgram * should be sent. The receiver is copied. * @param runLoopMode The run loop mode in which to perform the async send */ - (void)asyncSendData: (OFData *)data receiver: (const OFSocketAddress *)receiver runLoopMode: (OFRunLoopMode)runLoopMode; #ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref OFSocketAddress to which the datagram * should be sent. The receiver is copied. * @param block The block to call when the packet has been sent. It should * return the data for the next send with the same callback or nil * if it should not repeat. */ - (void)asyncSendData: (OFData *)data receiver: (const OFSocketAddress *)receiver block: (OFDatagramSocketAsyncSendDataBlock)block; /** * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref OFSocketAddress to which the datagram * should be sent. The receiver is copied. * @param runLoopMode The run loop mode in which to perform the async send * @param block The block to call when the packet has been sent. It should * return the data for the next send with the same callback or nil * if it should not repeat. */ - (void)asyncSendData: (OFData *)data receiver: (const OFSocketAddress *)receiver runLoopMode: (OFRunLoopMode)runLoopMode block: (OFDatagramSocketAsyncSendDataBlock)block; #endif /** * @brief Cancels all pending asynchronous requests on the socket. */ - (void)cancelAsyncRequests; |
︙ | ︙ |
Modified src/OFDatagramSocket.m from [3479c8733b] to [57abed2c44].
1 | /* | < < | > > > > > | | > > < < < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #ifndef _XOPEN_SOURCE_EXTENDED # define _XOPEN_SOURCE_EXTENDED #endif #define _HPUX_ALT_XOPEN_SOCKET_API #include <errno.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFDatagramSocket.h" #import "OFData.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFGetOptionFailedException.h" #import "OFInitializationFailedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFSetOptionFailedException.h" #import "OFSetOptionFailedException.h" #import "OFWriteFailedException.h" @implementation OFDatagramSocket @synthesize delegate = _delegate; + (void)initialize { if (self != [OFDatagramSocket class]) return; if (!OFSocketInit()) @throw [OFInitializationFailedException exceptionWithClass: self]; } + (instancetype)socket { return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; @try { if (self.class == [OFDatagramSocket class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } _socket = OFInvalidSocketHandle; _canBlock = true; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_socket != OFInvalidSocketHandle) [self close]; [super dealloc]; } - (id)copy { |
︙ | ︙ | |||
112 113 114 115 116 117 118 | if (fcntl(_socket, F_SETFL, flags) == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; _canBlock = canBlock; #elif defined(OF_WINDOWS) | | | | | | | | | | | | > > > > > | | < | | | | | | | | | | | | | | | | | | | | | | | | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | if (fcntl(_socket, F_SETFL, flags) == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; _canBlock = canBlock; #elif defined(OF_WINDOWS) u_long v = !canBlock; if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: OFSocketErrNo()]; _canBlock = canBlock; #else OF_UNRECOGNIZED_SELECTOR #endif } - (void)setCanSendToBroadcastAddresses: (bool)canSendToBroadcastAddresses { int v = canSendToBroadcastAddresses; if (setsockopt(_socket, SOL_SOCKET, SO_BROADCAST, (char *)&v, (socklen_t)sizeof(v)) != 0) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: OFSocketErrNo()]; #ifdef OF_WII _canSendToBroadcastAddresses = canSendToBroadcastAddresses; #endif } - (bool)canSendToBroadcastAddresses { #ifndef OF_WII int v; socklen_t len = sizeof(v); if (getsockopt(_socket, SOL_SOCKET, SO_BROADCAST, (char *)&v, &len) != 0 || len != sizeof(v)) @throw [OFGetOptionFailedException exceptionWithObject: self errNo: OFSocketErrNo()]; return v; #else return _canSendToBroadcastAddresses; #endif } - (size_t)receiveIntoBuffer: (void *)buffer length: (size_t)length sender: (OFSocketAddress *)sender { ssize_t ret; if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; sender->length = (socklen_t)sizeof(sender->sockaddr); #ifndef OF_WINDOWS if ((ret = recvfrom(_socket, buffer, length, 0, &sender->sockaddr.sockaddr, &sender->length)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: OFSocketErrNo()]; #else if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((ret = recvfrom(_socket, buffer, (int)length, 0, &sender->sockaddr.sockaddr, &sender->length)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: OFSocketErrNo()]; #endif switch (sender->sockaddr.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_IPX case AF_IPX: sender->family = OFSocketAddressFamilyIPX; break; #endif #ifdef OF_HAVE_UNIX_SOCKETS case AF_UNIX: sender->family = OFSocketAddressFamilyUNIX; break; #endif default: sender->family = OFSocketAddressFamilyUnknown; break; } return ret; } - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length { [self asyncReceiveIntoBuffer: buffer length: length runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode { [OFRunLoop of_addAsyncReceiveForDatagramSocket: self buffer: buffer length: length mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length block: (OFDatagramSocketAsyncReceiveBlock)block { [self asyncReceiveIntoBuffer: buffer length: length runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode block: (OFDatagramSocketAsyncReceiveBlock)block { [OFRunLoop of_addAsyncReceiveForDatagramSocket: self buffer: buffer length: length mode: runLoopMode block: block delegate: nil]; } #endif - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const OFSocketAddress *)receiver { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; #ifndef OF_WINDOWS ssize_t bytesWritten; if (length > SSIZE_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = sendto(_socket, (void *)buffer, length, 0, (struct sockaddr *)&receiver->sockaddr.sockaddr, receiver->length)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: OFSocketErrNo()]; #else int bytesWritten; if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = sendto(_socket, buffer, (int)length, 0, &receiver->sockaddr.sockaddr, receiver->length)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: OFSocketErrNo()]; #endif if ((size_t)bytesWritten != length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; } - (void)asyncSendData: (OFData *)data receiver: (const OFSocketAddress *)receiver { [self asyncSendData: data receiver: receiver runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncSendData: (OFData *)data receiver: (const OFSocketAddress *)receiver runLoopMode: (OFRunLoopMode)runLoopMode { [OFRunLoop of_addAsyncSendForDatagramSocket: self data: data receiver: receiver mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncSendData: (OFData *)data receiver: (const OFSocketAddress *)receiver block: (OFDatagramSocketAsyncSendDataBlock)block { [self asyncSendData: data receiver: receiver runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncSendData: (OFData *)data receiver: (const OFSocketAddress *)receiver runLoopMode: (OFRunLoopMode)runLoopMode block: (OFDatagramSocketAsyncSendDataBlock)block { [OFRunLoop of_addAsyncSendForDatagramSocket: self data: data receiver: receiver mode: runLoopMode block: block delegate: nil]; } #endif - (void)cancelAsyncRequests { [OFRunLoop of_cancelAsyncRequestsForObject: self mode: OFDefaultRunLoopMode]; } - (int)fileDescriptorForReading { #ifndef OF_WINDOWS return _socket; #else if (_socket == OFInvalidSocketHandle) return -1; if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } - (int)fileDescriptorForWriting { #ifndef OF_WINDOWS return _socket; #else if (_socket == OFInvalidSocketHandle) return -1; if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } - (void)close { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; closesocket(_socket); _socket = OFInvalidSocketHandle; } @end |
Modified src/OFDate.h from [b56f401ff6] to [f33ded2414].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
31 32 33 34 35 36 37 | */ #ifndef OF_DATE_M OF_SUBCLASSING_RESTRICTED #endif @interface OFDate: OFObject <OFCopying, OFComparing, OFSerialization, OFMessagePackRepresentation> { | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | */ #ifndef OF_DATE_M OF_SUBCLASSING_RESTRICTED #endif @interface OFDate: OFObject <OFCopying, OFComparing, OFSerialization, OFMessagePackRepresentation> { OFTimeInterval _seconds; } #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) OFDate *distantFuture; @property (class, readonly, nonatomic) OFDate *distantPast; #endif |
︙ | ︙ | |||
122 123 124 125 126 127 128 | * @brief The day of the year of the date in local time. */ @property (readonly, nonatomic) unsigned short localDayOfYear; /** * @brief The seconds since 1970-01-01T00:00:00Z. */ | | | | | | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | * @brief The day of the year of the date in local time. */ @property (readonly, nonatomic) unsigned short localDayOfYear; /** * @brief The seconds since 1970-01-01T00:00:00Z. */ @property (readonly, nonatomic) OFTimeInterval timeIntervalSince1970; /** * @brief The seconds the date is in the future. */ @property (readonly, nonatomic) OFTimeInterval timeIntervalSinceNow; /** * @brief Creates a new OFDate with the current date and time. * * @return A new, autoreleased OFDate with the current date and time */ + (instancetype)date; /** * @brief Creates a new OFDate with the specified date and time since * 1970-01-01T00:00:00Z. * * @param seconds The seconds since 1970-01-01T00:00:00Z * @return A new, autoreleased OFDate with the specified date and time */ + (instancetype)dateWithTimeIntervalSince1970: (OFTimeInterval)seconds; /** * @brief Creates a new OFDate with the specified date and time since now. * * @param seconds The seconds since now * @return A new, autoreleased OFDate with the specified date and time */ + (instancetype)dateWithTimeIntervalSinceNow: (OFTimeInterval)seconds; /** * @brief Creates a new OFDate with the specified string in the specified * format. * * The time zone used is UTC. See @ref dateWithLocalDateString:format: if you * want local time. |
︙ | ︙ | |||
215 216 217 218 219 220 221 | /** * @brief Initializes an already allocated OFDate with the specified date and * time since 1970-01-01T00:00:00Z. * * @param seconds The seconds since 1970-01-01T00:00:00Z * @return An initialized OFDate with the specified date and time */ | | | | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | /** * @brief Initializes an already allocated OFDate with the specified date and * time since 1970-01-01T00:00:00Z. * * @param seconds The seconds since 1970-01-01T00:00:00Z * @return An initialized OFDate with the specified date and time */ - (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds OF_DESIGNATED_INITIALIZER; /** * @brief Initializes an already allocated OFDate with the specified date and * time since now. * * @param seconds The seconds since now * @return An initialized OFDate with the specified date and time */ - (instancetype)initWithTimeIntervalSinceNow: (OFTimeInterval)seconds; /** * @brief Initializes an already allocated OFDate with the specified string in * the specified format. * * The time zone used is UTC. If a time zone is specified anyway, an * OFInvalidFormatException is thrown. See @ref initWithLocalDateString:format: |
︙ | ︙ | |||
265 266 267 268 269 270 271 272 273 274 275 276 277 278 | * @param string The string describing the date * @param format The format of the string describing the date * @return An initialized OFDate with the specified date and time */ - (instancetype)initWithLocalDateString: (OFString *)string format: (OFString *)format; /** * @brief Creates a string of the date with the specified format. * * See the man page for `strftime` for information on the format. * * @param format The format for the date string * @return A new, autoreleased OFString | > > > > > > > > | 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | * @param string The string describing the date * @param format The format of the string describing the date * @return An initialized OFDate with the specified date and time */ - (instancetype)initWithLocalDateString: (OFString *)string format: (OFString *)format; /** * @brief Compares the date to another date. * * @param date The date to compare the date to * @return The result of the comparison */ - (OFComparisonResult)compare: (OFDate *)date; /** * @brief Creates a string of the date with the specified format. * * See the man page for `strftime` for information on the format. * * @param format The format for the date string * @return A new, autoreleased OFString |
︙ | ︙ | |||
311 312 313 314 315 316 317 | /** * @brief Returns the seconds the receiver is after the date. * * @param otherDate Date date to generate the difference with receiver * @return The seconds the receiver is after the date. */ | | | | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | /** * @brief Returns the seconds the receiver is after the date. * * @param otherDate Date date to generate the difference with receiver * @return The seconds the receiver is after the date. */ - (OFTimeInterval)timeIntervalSinceDate: (OFDate *)otherDate; /** * @brief Creates a new date with the specified time interval added. * * @param seconds The seconds after the date * @return A new, autoreleased OFDate */ - (OFDate *)dateByAddingTimeInterval: (OFTimeInterval)seconds; @end OF_ASSUME_NONNULL_END |
Modified src/OFDate.m from [b60c2c0014] to [ebc414dd12].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #import "OFDate.h" #import "OFData.h" #import "OFDictionary.h" #import "OFMessagePackExtension.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFString.h" #import "OFSystemInfo.h" #import "OFXMLElement.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" | > < < | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #import "OFDate.h" #import "OFData.h" #import "OFDictionary.h" #import "OFMessagePackExtension.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFStrPTime.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFXMLElement.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #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; @end |
︙ | ︙ | |||
89 90 91 92 93 94 95 | static void initDistantPast(void) { distantPast = [[OFDateSingleton alloc] initWithTimeIntervalSince1970: -62167219200.0]; } | | | | | > > > > > > | | | | | | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | static void initDistantPast(void) { distantPast = [[OFDateSingleton alloc] initWithTimeIntervalSince1970: -62167219200.0]; } static OFTimeInterval now(void) { struct timeval tv; OFTimeInterval seconds; OFEnsure(gettimeofday(&tv, NULL) == 0); seconds = tv.tv_sec; seconds += (OFTimeInterval)tv.tv_usec / 1000000; return seconds; } #if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \ defined(OF_HAVE_THREADS) static OFMutex *mutex; static void releaseMutex(void) { [mutex release]; } #endif #ifdef OF_WINDOWS static __time64_t (*_mktime64FuncPtr)(struct tm *); #endif #ifdef HAVE_GMTIME_R # define GMTIME_RET(field) \ OFTimeInterval timeInterval = self.timeIntervalSince1970; \ time_t seconds = (time_t)timeInterval; \ struct tm tm; \ \ if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ if (gmtime_r(&seconds, &tm) == NULL) \ @throw [OFOutOfRangeException exception]; \ \ return tm.field; # define LOCALTIME_RET(field) \ OFTimeInterval timeInterval = self.timeIntervalSince1970; \ time_t seconds = (time_t)timeInterval; \ struct tm tm; \ \ if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ if (localtime_r(&seconds, &tm) == NULL) \ @throw [OFOutOfRangeException exception]; \ \ return tm.field; #else # ifdef OF_HAVE_THREADS # define GMTIME_RET(field) \ OFTimeInterval timeInterval = self.timeIntervalSince1970; \ time_t seconds = (time_t)timeInterval; \ struct tm *tm; \ \ if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ [mutex lock]; \ \ @try { \ if ((tm = gmtime(&seconds)) == NULL) \ @throw [OFOutOfRangeException exception]; \ \ return tm->field; \ } @finally { \ [mutex unlock]; \ } # define LOCALTIME_RET(field) \ OFTimeInterval timeInterval = self.timeIntervalSince1970; \ time_t seconds = (time_t)timeInterval; \ struct tm *tm; \ \ if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ [mutex lock]; \ \ @try { \ if ((tm = localtime(&seconds)) == NULL) \ @throw [OFOutOfRangeException exception]; \ \ return tm->field; \ } @finally { \ [mutex unlock]; \ } # else # define GMTIME_RET(field) \ OFTimeInterval timeInterval = self.timeIntervalSince1970; \ time_t seconds = (time_t)timeInterval; \ struct tm *tm; \ \ if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ if ((tm = gmtime(&seconds)) == NULL) \ @throw [OFOutOfRangeException exception]; \ \ return tm->field; # define LOCALTIME_RET(field) \ OFTimeInterval timeInterval = self.timeIntervalSince1970; \ time_t seconds = (time_t)timeInterval; \ struct tm *tm; \ \ if (seconds != trunc(timeInterval)) \ @throw [OFOutOfRangeException exception]; \ \ if ((tm = localtime(&seconds)) == NULL) \ |
︙ | ︙ | |||
269 270 271 272 273 274 275 | - (void)release { } - (unsigned int)retainCount { | | | | | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | - (void)release { } - (unsigned int)retainCount { return OFMaxRetainCount; } @end @implementation OFDatePlaceholder #ifdef __clang__ /* We intentionally don't call into super, so silence the warning. */ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wunknown-pragmas" # pragma clang diagnostic ignored "-Wobjc-designated-initializers" #endif - (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds { #if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX uint64_t value; #endif if (seconds == 0) { static OFOnceControl once = OFOnceControlInitValue; OFOnce(&once, initZeroDate); return (id)zeroDate; } #if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX value = OFFromBigEndian64(OFDoubleToRawUInt64(OFToBigEndianDouble( seconds))); /* Almost all dates fall into this range. */ if (value & (UINT64_C(4) << 60)) { id ret = objc_createTaggedPointer(dateTag, value & ~(UINT64_C(4) << 60)); |
︙ | ︙ | |||
315 316 317 318 319 320 321 | #ifdef __clang__ # pragma clang diagnostic pop #endif @end #if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX @implementation OFTaggedPointerDate | | | > | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 | #ifdef __clang__ # pragma clang diagnostic pop #endif @end #if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX @implementation OFTaggedPointerDate - (OFTimeInterval)timeIntervalSince1970 { uint64_t value = (uint64_t)object_getTaggedPointerValue(self); value |= UINT64_C(4) << 60; return OFFromBigEndianDouble(OFRawUInt64ToDouble(OFToBigEndian64( value))); } @end #endif @implementation OFDate + (void)initialize { #ifdef OF_WINDOWS HMODULE module; #endif if (self != [OFDate class]) return; placeholder.isa = [OFDatePlaceholder class]; #if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \ defined(OF_HAVE_THREADS) mutex = [[OFMutex alloc] init]; atexit(releaseMutex); #endif #ifdef OF_WINDOWS if ((module = LoadLibrary("msvcrt.dll")) != NULL) _mktime64FuncPtr = (__time64_t (*)(struct tm *)) GetProcAddress(module, "_mktime64"); #endif #if defined(OF_OBJFW_RUNTIME) && UINTPTR_MAX == UINT64_MAX dateTag = objc_registerTaggedPointerClass([OFTaggedPointerDate class]); #endif } |
︙ | ︙ | |||
373 374 375 376 377 378 379 | } + (instancetype)date { return [[[self alloc] init] autorelease]; } | | | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | } + (instancetype)date { return [[[self alloc] init] autorelease]; } + (instancetype)dateWithTimeIntervalSince1970: (OFTimeInterval)seconds { return [[[self alloc] initWithTimeIntervalSince1970: seconds] autorelease]; } + (instancetype)dateWithTimeIntervalSinceNow: (OFTimeInterval)seconds { return [[[self alloc] initWithTimeIntervalSinceNow: seconds] autorelease]; } + (instancetype)dateWithDateString: (OFString *)string format: (OFString *)format |
︙ | ︙ | |||
401 402 403 404 405 406 407 | { return [[[self alloc] initWithLocalDateString: string format: format] autorelease]; } + (instancetype)distantFuture { | | | | | | | | | | | | | | | | | | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 | { return [[[self alloc] initWithLocalDateString: string format: format] autorelease]; } + (instancetype)distantFuture { static OFOnceControl once = OFOnceControlInitValue; OFOnce(&once, initDistantFuture); return distantFuture; } + (instancetype)distantPast { static OFOnceControl once = OFOnceControlInitValue; OFOnce(&once, initDistantPast); return distantPast; } - (instancetype)init { return [self initWithTimeIntervalSince1970: now()]; } - (instancetype)initWithTimeIntervalSince1970: (OFTimeInterval)seconds { self = [super init]; _seconds = seconds; return self; } - (instancetype)initWithTimeIntervalSinceNow: (OFTimeInterval)seconds { return [self initWithTimeIntervalSince1970: now() + seconds]; } - (instancetype)initWithDateString: (OFString *)string format: (OFString *)format { void *pool = objc_autoreleasePoolPush(); const char *UTF8String = string.UTF8String; struct tm tm = { .tm_isdst = -1 }; short tz = 0; if (OFStrPTime(UTF8String, format.UTF8String, &tm, &tz) != UTF8String + string.UTF8StringLength) @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); return [self initWithTimeIntervalSince1970: tmAndTzToTime(&tm, tz)]; } - (instancetype)initWithLocalDateString: (OFString *)string format: (OFString *)format { void *pool = objc_autoreleasePoolPush(); const char *UTF8String = string.UTF8String; struct tm tm = { .tm_isdst = -1 }; /* * OFStrPTime() can never set this to SHRT_MAX, no matter what is * passed to it, so this is a safe way to figure out if the date * contains a time zone. */ short tz = SHRT_MAX; OFTimeInterval seconds; if (OFStrPTime(UTF8String, format.UTF8String, &tm, &tz) != UTF8String + string.UTF8StringLength) @throw [OFInvalidFormatException exception]; if (tz == SHRT_MAX) { #ifdef OF_WINDOWS if (_mktime64FuncPtr != NULL) { if ((seconds = _mktime64FuncPtr(&tm)) == -1) @throw [OFInvalidFormatException exception]; } else { #endif if ((seconds = mktime(&tm)) == -1) @throw [OFInvalidFormatException exception]; #ifdef OF_WINDOWS } #endif } else seconds = tmAndTzToTime(&tm, tz); objc_autoreleasePoolPop(pool); return [self initWithTimeIntervalSince1970: seconds]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { OFTimeInterval seconds; @try { void *pool = objc_autoreleasePoolPush(); unsigned long long value; if (![element.name isEqual: @"OFDate"] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; value = [element unsignedLongLongValueWithBase: 16]; if (value > UINT64_MAX) @throw [OFOutOfRangeException exception]; seconds = OFFromBigEndianDouble(OFRawUInt64ToDouble( OFToBigEndian64(value))); objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
536 537 538 539 540 541 542 | return false; return true; } - (unsigned long)hash { | | | | | | < < | | | < < | | | | | | | | | | < | < | | | < | | 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 | return false; return true; } - (unsigned long)hash { unsigned long hash; double tmp; OFHashInit(&hash); tmp = OFToLittleEndianDouble(self.timeIntervalSince1970); for (size_t i = 0; i < sizeof(double); i++) OFHashAdd(&hash, ((char *)&tmp)[i]); OFHashFinalize(&hash); return hash; } - (id)copy { return [self retain]; } - (OFComparisonResult)compare: (OFDate *)date { if (![date isKindOfClass: [OFDate class]]) @throw [OFInvalidArgumentException exception]; if (self.timeIntervalSince1970 < date.timeIntervalSince1970) return OFOrderedAscending; if (self.timeIntervalSince1970 > date.timeIntervalSince1970) return OFOrderedDescending; return OFOrderedSame; } - (OFString *)description { return [self dateStringWithFormat: @"%Y-%m-%dT%H:%M:%SZ"]; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: @"OFDate" namespace: OFSerializationNS]; element.stringValue = [OFString stringWithFormat: @"%016" PRIx64, OFFromBigEndian64(OFDoubleToRawUInt64(OFToBigEndianDouble( self.timeIntervalSince1970)))]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } - (OFData *)messagePackRepresentation { void *pool = objc_autoreleasePoolPush(); OFTimeInterval timeInterval = self.timeIntervalSince1970; int64_t seconds = (int64_t)timeInterval; uint32_t nanoseconds = (uint32_t)((timeInterval - trunc(timeInterval)) * 1000000000); OFData *ret; if (seconds >= 0 && seconds < 0x400000000) { if (seconds <= UINT32_MAX && nanoseconds == 0) { uint32_t seconds32 = (uint32_t)seconds; OFData *data; seconds32 = OFToBigEndian32(seconds32); data = [OFData dataWithItems: &seconds32 count: sizeof(seconds32)]; ret = [[OFMessagePackExtension extensionWithType: -1 data: data] messagePackRepresentation]; } else { uint64_t combined = ((uint64_t)nanoseconds << 34) | (uint64_t)seconds; OFData *data; combined = OFToBigEndian64(combined); data = [OFData dataWithItems: &combined count: sizeof(combined)]; ret = [[OFMessagePackExtension extensionWithType: -1 data: data] messagePackRepresentation]; } } else { OFMutableData *data = [OFMutableData dataWithCapacity: 12]; nanoseconds = OFToBigEndian32(nanoseconds); [data addItems: &nanoseconds count: sizeof(nanoseconds)]; seconds = OFToBigEndian64(seconds); [data addItems: &seconds count: sizeof(seconds)]; ret = [[OFMessagePackExtension extensionWithType: -1 data: data] messagePackRepresentation]; } [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (unsigned long)microsecond { OFTimeInterval timeInterval = self.timeIntervalSince1970; return (unsigned long)((timeInterval - trunc(timeInterval)) * 1000000); } - (unsigned char)second { GMTIME_RET(tm_sec) |
︙ | ︙ | |||
739 740 741 742 743 744 745 | { LOCALTIME_RET(tm_yday + 1) } - (OFString *)dateStringWithFormat: (OFConstantString *)format { OFString *ret; | | | 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 | { LOCALTIME_RET(tm_yday + 1) } - (OFString *)dateStringWithFormat: (OFConstantString *)format { OFString *ret; OFTimeInterval timeInterval = self.timeIntervalSince1970; time_t seconds = (time_t)timeInterval; struct tm tm; size_t pageSize; #ifndef OF_WINDOWS char *buffer; #else wchar_t *buffer; |
︙ | ︙ | |||
775 776 777 778 779 780 781 | } @finally { [mutex unlock]; } # endif #endif pageSize = [OFSystemInfo pageSize]; | | | | | 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 | } @finally { [mutex unlock]; } # endif #endif pageSize = [OFSystemInfo pageSize]; buffer = OFAllocMemory(1, pageSize); @try { #ifndef OF_WINDOWS if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0) @throw [OFOutOfRangeException exception]; ret = [OFString stringWithUTF8String: buffer]; #else if (wcsftime(buffer, pageSize / sizeof(wchar_t), format.UTF16String, &tm) == 0) @throw [OFOutOfRangeException exception]; ret = [OFString stringWithUTF16String: buffer]; #endif } @finally { OFFreeMemory(buffer); } return ret; } - (OFString *)localDateStringWithFormat: (OFConstantString *)format { OFString *ret; OFTimeInterval timeInterval = self.timeIntervalSince1970; time_t seconds = (time_t)timeInterval; struct tm tm; size_t pageSize; #ifndef OF_WINDOWS char *buffer; #else wchar_t *buffer; |
︙ | ︙ | |||
835 836 837 838 839 840 841 | } @finally { [mutex unlock]; } # endif #endif pageSize = [OFSystemInfo pageSize]; | | | | | | | | | | | | | 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 | } @finally { [mutex unlock]; } # endif #endif pageSize = [OFSystemInfo pageSize]; buffer = OFAllocMemory(1, pageSize); @try { #ifndef OF_WINDOWS if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0) @throw [OFOutOfRangeException exception]; ret = [OFString stringWithUTF8String: buffer]; #else if (wcsftime(buffer, pageSize / sizeof(wchar_t), format.UTF16String, &tm) == 0) @throw [OFOutOfRangeException exception]; ret = [OFString stringWithUTF16String: buffer]; #endif } @finally { OFFreeMemory(buffer); } return ret; } - (OFDate *)earlierDate: (OFDate *)otherDate { if (otherDate == nil) return self; if ([self compare: otherDate] == OFOrderedDescending) return otherDate; return self; } - (OFDate *)laterDate: (OFDate *)otherDate { if (otherDate == nil) return self; if ([self compare: otherDate] == OFOrderedAscending) return otherDate; return self; } - (OFTimeInterval)timeIntervalSince1970 { return _seconds; } - (OFTimeInterval)timeIntervalSinceDate: (OFDate *)otherDate { return self.timeIntervalSince1970 - otherDate.timeIntervalSince1970; } - (OFTimeInterval)timeIntervalSinceNow { struct timeval t; OFTimeInterval seconds; OFEnsure(gettimeofday(&t, NULL) == 0); seconds = t.tv_sec; seconds += (OFTimeInterval)t.tv_usec / 1000000; return self.timeIntervalSince1970 - seconds; } - (OFDate *)dateByAddingTimeInterval: (OFTimeInterval)seconds { return [OFDate dateWithTimeIntervalSince1970: self.timeIntervalSince1970 + seconds]; } @end |
Modified src/OFDictionary.h from [ce711756a9] to [a605581e45].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
32 33 34 35 36 37 38 | #import "OFMessagePackRepresentation.h" OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); #ifdef OF_HAVE_BLOCKS | > > > > > > > > | | > > > > > > > | > > > > > > > > | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #import "OFMessagePackRepresentation.h" 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 * * @brief An abstract class for storing objects in a dictionary. * |
︙ | ︙ | |||
96 97 98 99 100 101 102 | /** * @brief Creates a new OFDictionary with the specified key and object. * * @param key The key * @param object The object * @return A new autoreleased OFDictionary */ | | < < | | | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | /** * @brief Creates a new OFDictionary with the specified key and object. * * @param key The key * @param object The object * @return A new autoreleased OFDictionary */ + (instancetype)dictionaryWithObject: (ObjectType)object forKey: (KeyType)key; /** * @brief Creates a new OFDictionary with the specified keys and objects. * * @param keys An array of keys * @param objects An array of objects * @return A new autoreleased OFDictionary */ + (instancetype)dictionaryWithObjects: (OFArray OF_GENERIC(ObjectType) *)objects forKeys: (OFArray OF_GENERIC(KeyType) *)keys; /** * @brief Creates a new OFDictionary with the specified keys and objects. * * @param keys An array of keys * @param objects An array of objects * @param count The number of objects in the arrays |
︙ | ︙ | |||
150 151 152 153 154 155 156 | * @brief Initializes an already allocated OFDictionary with the specified key * and object. * * @param key The key * @param object The object * @return An initialized OFDictionary */ | | < | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | * @brief Initializes an already allocated OFDictionary with the specified key * and object. * * @param key The key * @param object The object * @return An initialized OFDictionary */ - (instancetype)initWithObject: (ObjectType)object forKey: (KeyType)key; /** * @brief Initializes an already allocated OFDictionary with the specified keys * and objects. * * @param keys An array of keys * @param objects An array of objects |
︙ | ︙ | |||
194 195 196 197 198 199 200 | * @brief Initializes an already allocated OFDictionary with the specified key * and va_list. * * @param firstKey The first key * @param arguments A va_list of the other arguments * @return An initialized OFDictionary */ | | < | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | * @brief Initializes an already allocated OFDictionary with the specified key * and va_list. * * @param firstKey The first key * @param arguments A va_list of the other arguments * @return An initialized OFDictionary */ - (instancetype)initWithKey: (KeyType)firstKey arguments: (va_list)arguments; /** * @brief Returns the object for the given key or `nil` if the key was not * found. * * @warning The returned object is *not* retained and autoreleased for * performance reasons! |
︙ | ︙ | |||
232 233 234 235 236 237 238 | * * This is equivalent to OFMutableDictionary#setObject:forKey:. If the * dictionary is immutable, an @ref OFUndefinedKeyException is thrown. * * @param key The key to set * @param value The value to set the key to */ | | < | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | * * This is equivalent to OFMutableDictionary#setObject:forKey:. If the * dictionary is immutable, an @ref OFUndefinedKeyException is thrown. * * @param key The key to set * @param value The value to set the key to */ - (void)setValue: (nullable id)value forKey: (OFString *)key; /** * @brief Checks whether the dictionary contains an object equal to the * specified object. * * @param object The object which is checked for being in the dictionary * @return A boolean whether the dictionary contains the specified object |
︙ | ︙ | |||
274 275 276 277 278 279 280 | #ifdef OF_HAVE_BLOCKS /** * @brief Executes a block for each key / object pair. * * @param block The block to execute for each key / object pair. */ | | < | | | | | 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | #ifdef OF_HAVE_BLOCKS /** * @brief Executes a block for each key / object pair. * * @param block The block to execute for each key / object pair. */ - (void)enumerateKeysAndObjectsUsingBlock: (OFDictionaryEnumerationBlock)block; /** * @brief Creates a new dictionary, mapping each object using the specified * block. * * @param block A block which maps an object for each object * @return A new autoreleased OFDictionary */ - (OFDictionary OF_GENERIC(KeyType, id) *) mappedDictionaryUsingBlock: (OFDictionaryMapBlock)block; /** * @brief Creates a new dictionary, only containing the objects for which the * block returns true. * * @param block A block which determines if the object should be in the new * dictionary * @return A new autoreleased OFDictionary */ - (OFDictionary OF_GENERIC(KeyType, ObjectType) *) filteredDictionaryUsingBlock: (OFDictionaryFilterBlock)block; #endif #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef KeyType # undef ObjectType #endif @end |
︙ | ︙ |
Modified src/OFDictionary.m from [505aa3e10f] to [a48510c034].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | static struct { Class isa; } placeholder; static OFCharacterSet *URLQueryPartAllowedCharacterSet = nil; @interface OFDictionary () | | > | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | static struct { Class isa; } placeholder; static OFCharacterSet *URLQueryPartAllowedCharacterSet = nil; @interface OFDictionary () - (OFString *) of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options depth: (size_t)depth; @end @interface OFDictionaryPlaceholder: OFDictionary @end OF_DIRECT_MEMBERS @interface OFDictionaryObjectEnumerator: OFEnumerator |
︙ | ︙ | |||
71 72 73 74 75 76 77 | - (instancetype)initWithDictionary: (OFDictionary *)dictionary { return (id)[[OFMapTableDictionary alloc] initWithDictionary: dictionary]; } | | < | < | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | - (instancetype)initWithDictionary: (OFDictionary *)dictionary { return (id)[[OFMapTableDictionary alloc] initWithDictionary: dictionary]; } - (instancetype)initWithObject: (id)object forKey: (id)key { return (id)[[OFMapTableDictionary alloc] initWithObject: object forKey: key]; } - (instancetype)initWithObjects: (OFArray *)objects forKeys: (OFArray *)keys { return (id)[[OFMapTableDictionary alloc] initWithObjects: objects forKeys: keys]; } - (instancetype)initWithObjects: (id const *)objects forKeys: (id const *)keys |
︙ | ︙ | |||
171 172 173 174 175 176 177 | - (void)release { } - (unsigned int)retainCount { | | | | | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | - (void)release { } - (unsigned int)retainCount { return OFMaxRetainCount; } - (bool)characterIsMember: (OFUnichar)character { if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; switch (character) { case '-': case '.': case '_': case '~': |
︙ | ︙ | |||
226 227 228 229 230 231 232 | + (instancetype)dictionaryWithDictionary: (OFDictionary *)dictionary { return [[(OFDictionary *)[self alloc] initWithDictionary: dictionary] autorelease]; } | | < | < | | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | + (instancetype)dictionaryWithDictionary: (OFDictionary *)dictionary { return [[(OFDictionary *)[self alloc] initWithDictionary: dictionary] autorelease]; } + (instancetype)dictionaryWithObject: (id)object forKey: (id)key { return [[[self alloc] initWithObject: object forKey: key] autorelease]; } + (instancetype)dictionaryWithObjects: (OFArray *)objects forKeys: (OFArray *)keys { return [[[self alloc] initWithObjects: objects forKeys: keys] autorelease]; } + (instancetype)dictionaryWithObjects: (id const *)objects forKeys: (id const *)keys count: (size_t)count { return [[[self alloc] initWithObjects: objects forKeys: keys count: count] autorelease]; } + (instancetype)dictionaryWithKeysAndObjects: (id)firstKey, ... |
︙ | ︙ | |||
283 284 285 286 287 288 289 | } - (instancetype)initWithDictionary: (OFDictionary *)dictionary { OF_INVALID_INIT_METHOD } | | < | < | < < | < | < | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | } - (instancetype)initWithDictionary: (OFDictionary *)dictionary { OF_INVALID_INIT_METHOD } - (instancetype)initWithObject: (id)object forKey: (id)key { if (key == nil || object == nil) @throw [OFInvalidArgumentException exception]; return [self initWithKeysAndObjects: key, object, nil]; } - (instancetype)initWithObjects: (OFArray *)objects_ forKeys: (OFArray *)keys_ { id const *objects, *keys; size_t count; @try { count = objects_.count; if (count != keys_.count) @throw [OFInvalidArgumentException exception]; objects = objects_.objects; keys = keys_.objects; } @catch (id e) { [self release]; @throw e; } return [self initWithObjects: objects forKeys: keys count: count]; } - (instancetype)initWithObjects: (id const *)objects forKeys: (id const *)keys count: (size_t)count { OF_INVALID_INIT_METHOD } - (instancetype)initWithKeysAndObjects: (id)firstKey, ... { id ret; va_list arguments; va_start(arguments, firstKey); ret = [self initWithKey: firstKey arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithKey: (id)firstKey arguments: (va_list)arguments { OF_INVALID_INIT_METHOD } - (instancetype)initWithSerialization: (OFXMLElement *)element { OF_INVALID_INIT_METHOD |
︙ | ︙ | |||
365 366 367 368 369 370 371 | { if ([key isEqual: @"@count"]) return [super valueForKey: @"count"]; return [self objectForKey: key]; } | | < | < | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | { if ([key isEqual: @"@count"]) return [super valueForKey: @"count"]; return [self objectForKey: key]; } - (void)setValue: (id)value forKey: (OFString *)key { if (![self isKindOfClass: [OFMutableDictionary class]]) @throw [OFUndefinedKeyException exceptionWithObject: self key: key value: value]; [(OFMutableDictionary *)self setObject: value forKey: key]; } - (size_t)count { OF_UNRECOGNIZED_SELECTOR } |
︙ | ︙ | |||
517 518 519 520 521 522 523 | - (OFEnumerator *)objectEnumerator { return [[[OFDictionaryObjectEnumerator alloc] initWithDictionary: self] autorelease]; } | | | 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 | - (OFEnumerator *)objectEnumerator { return [[[OFDictionaryObjectEnumerator alloc] initWithDictionary: self] autorelease]; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { OFEnumerator *enumerator; int i; memcpy(&enumerator, state->extra, sizeof(enumerator)); |
︙ | ︙ | |||
547 548 549 550 551 552 553 | objects[i] = object; } return i; } #ifdef OF_HAVE_BLOCKS | | < | | < | < | < | 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 | objects[i] = object; } return i; } #ifdef OF_HAVE_BLOCKS - (void)enumerateKeysAndObjectsUsingBlock: (OFDictionaryEnumerationBlock)block { bool stop = false; for (id key in self) { block(key, [self objectForKey: key], &stop); if (stop) break; } } - (OFDictionary *)mappedDictionaryUsingBlock: (OFDictionaryMapBlock)block { OFMutableDictionary *new = [OFMutableDictionary dictionary]; [self enumerateKeysAndObjectsUsingBlock: ^ (id key, id object, bool *stop) { [new setObject: block(key, object) forKey: key]; }]; [new makeImmutable]; return new; } - (OFDictionary *)filteredDictionaryUsingBlock: (OFDictionaryFilterBlock)block { OFMutableDictionary *new = [OFMutableDictionary dictionary]; [self enumerateKeysAndObjectsUsingBlock: ^ (id key, id object, bool *stop) { if (block(key, object)) [new setObject: object forKey: key]; }]; [new makeImmutable]; return new; } #endif |
︙ | ︙ | |||
642 643 644 645 646 647 648 | [ret appendString: object.description]; if (++i < count) [ret appendString: @";\n"]; objc_autoreleasePoolPop(pool2); } | | < | 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 | [ret appendString: object.description]; if (++i < count) [ret appendString: @";\n"]; objc_autoreleasePoolPop(pool2); } [ret replaceOccurrencesOfString: @"\n" withString: @"\n\t"]; [ret appendString: @";\n}"]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; |
︙ | ︙ | |||
694 695 696 697 698 699 700 | void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; OFEnumerator *keyEnumerator, *objectEnumerator; id <OFSerialization> key, object; if ([self isKindOfClass: [OFMutableDictionary class]]) element = [OFXMLElement elementWithName: @"OFMutableDictionary" | | | | | | < | > | < | > | | | | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 | void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; OFEnumerator *keyEnumerator, *objectEnumerator; id <OFSerialization> key, object; if ([self isKindOfClass: [OFMutableDictionary class]]) element = [OFXMLElement elementWithName: @"OFMutableDictionary" namespace: OFSerializationNS]; else element = [OFXMLElement elementWithName: @"OFDictionary" namespace: OFSerializationNS]; keyEnumerator = [self keyEnumerator]; objectEnumerator = [self objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); OFXMLElement *keyElement, *objectElement; keyElement = [OFXMLElement elementWithName: @"key" namespace: OFSerializationNS]; [keyElement addChild: key.XMLElementBySerializing]; objectElement = [OFXMLElement elementWithName: @"object" namespace: OFSerializationNS]; [objectElement addChild: object.XMLElementBySerializing]; [element addChild: keyElement]; [element addChild: objectElement]; objc_autoreleasePoolPop(pool2); } [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } - (OFString *)JSONRepresentation { return [self of_JSONRepresentationWithOptions: 0 depth: 0]; } - (OFString *)JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options { return [self of_JSONRepresentationWithOptions: options depth: 0]; } - (OFString *) of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options depth: (size_t)depth { OFMutableString *JSON = [OFMutableString stringWithString: @"{"]; void *pool = objc_autoreleasePoolPush(); OFEnumerator *keyEnumerator = [self keyEnumerator]; OFEnumerator *objectEnumerator = [self objectEnumerator]; size_t i, count = self.count; id key, object; if (options & OFJSONRepresentationOptionPretty) { OFMutableString *indentation = [OFMutableString string]; for (i = 0; i < depth; i++) [indentation appendString: @"\t"]; [JSON appendString: @"\n"]; i = 0; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); int identifierOptions = options | OFJSONRepresentationOptionIsIdentifier; if (![key isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; [JSON appendString: indentation]; [JSON appendString: @"\t"]; [JSON appendString: [key |
︙ | ︙ | |||
794 795 796 797 798 799 800 | [JSON appendString: indentation]; } else { i = 0; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); int identifierOptions = | | | 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 | [JSON appendString: indentation]; } else { i = 0; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); int identifierOptions = options | OFJSONRepresentationOptionIsIdentifier; if (![key isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; [JSON appendString: [key of_JSONRepresentationWithOptions: identifierOptions depth: depth + 1]]; |
︙ | ︙ | |||
838 839 840 841 842 843 844 | count = self.count; if (count <= 15) { uint8_t tmp = 0x80 | ((uint8_t)count & 0xF); [data addItem: &tmp]; } else if (count <= UINT16_MAX) { uint8_t type = 0xDE; | | | < | | < | < | < | 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 | count = self.count; if (count <= 15) { uint8_t tmp = 0x80 | ((uint8_t)count & 0xF); [data addItem: &tmp]; } else if (count <= UINT16_MAX) { uint8_t type = 0xDE; uint16_t tmp = OFToBigEndian16((uint16_t)count); [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (count <= UINT32_MAX) { uint8_t type = 0xDF; uint32_t tmp = OFToBigEndian32((uint32_t)count); [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; pool = objc_autoreleasePoolPush(); i = 0; keyEnumerator = [self keyEnumerator]; objectEnumerator = [self objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); OFData *child; i++; child = key.messagePackRepresentation; [data addItems: child.items count: child.count]; child = object.messagePackRepresentation; [data addItems: child.items count: child.count]; objc_autoreleasePoolPop(pool2); } assert(i == count); [data makeImmutable]; |
︙ | ︙ |
Modified src/OFEnumerator.h from [234c3f2385] to [514f228b0c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFEnumerator OF_GENERIC(ObjectType); /** | | > > > > | | < < | > > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFEnumerator OF_GENERIC(ObjectType); /** * @protocol OFEnumeration OFEnumerator.h ObjFW/OFEnumerator.h * * @brief A protocol for getting an enumerator for the object. * * If the class conforming to OFEnumeration is using lightweight generics, the * only method, @ref objectEnumerator, should be overridden to use lightweight * generics. */ @protocol OFEnumeration /** * @brief Returns an OFEnumerator to enumerate through all objects of the * collection. * * @return An OFEnumerator to enumerate through all objects of the collection */ - (OFEnumerator *)objectEnumerator; @end /* * This needs to be exactly like this because it's hard-coded in the compiler. * * We need this bad check to see if we already imported Cocoa, which defines * this as well. */ /** * @struct OFFastEnumerationState OFEnumerator.h ObjFW/OFEnumerator.h * * @brief State information for fast enumerations. */ 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; /** 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 * * @brief A protocol for fast enumeration. * |
︙ | ︙ | |||
77 78 79 80 81 82 83 | * * @param state Context information for the enumeration * @param objects A pointer to an array where to put the objects * @param count The number of objects that can be stored at objects * @return The number of objects returned in objects or 0 when the enumeration * finished. */ | | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | * * @param state Context information for the enumeration * @param objects A pointer to an array where to put the objects * @param count The number of objects that can be stored at objects * @return The number of objects returned in objects or 0 when the enumeration * finished. */ - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id __unsafe_unretained _Nonnull *_Nonnull) objects count: (int)count; @end /** * @class OFEnumerator OFEnumerator.h ObjFW/OFEnumerator.h |
︙ | ︙ |
Modified src/OFEnumerator.m from [47ad878ce8] to [bb10b4629e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
55 56 57 58 59 60 61 | [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { int i; state->itemsPtr = objects; state->mutationsPtr = (unsigned long *)self; |
︙ | ︙ |
Modified src/OFEpollKernelEventObserver.h from [10f634c6df] to [d3c4bbd7da].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFEpollKernelEventObserver.m from [5306d06560] to [ddd2075d1e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
31 32 33 34 35 36 37 | #import "OFArray.h" #import "OFMapTable.h" #import "OFNull.h" #import "OFInitializationFailedException.h" #import "OFObserveFailedException.h" | | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #import "OFArray.h" #import "OFMapTable.h" #import "OFNull.h" #import "OFInitializationFailedException.h" #import "OFObserveFailedException.h" #define eventListSize 64 static const OFMapTableFunctions mapFunctions = { NULL }; @implementation OFEpollKernelEventObserver - (instancetype)init { self = [super init]; @try { |
︙ | ︙ | |||
185 186 187 188 189 190 191 | [self of_removeObject: object fileDescriptor: object.fileDescriptorForWriting events: EPOLLOUT]; [super removeObjectForWriting: object]; } | | | | | | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | [self of_removeObject: object fileDescriptor: object.fileDescriptorForWriting events: EPOLLOUT]; [super removeObjectForWriting: object]; } - (void)observeForTimeInterval: (OFTimeInterval)timeInterval { OFNull *nullObject = [OFNull null]; struct epoll_event eventList[eventListSize]; int events; if ([self of_processReadBuffers]) return; events = epoll_wait(_epfd, eventList, eventListSize, (timeInterval != -1 ? timeInterval * 1000 : -1)); if (events < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; for (int i = 0; i < events; i++) { if (eventList[i].events & EPOLLIN) { void *pool = objc_autoreleasePoolPush(); if (eventList[i].data.ptr == nullObject) { char buffer; OFEnsure(read(_cancelFD[0], &buffer, 1) == 1); continue; } if ([_delegate respondsToSelector: @selector(objectIsReadyForReading:)]) [_delegate objectIsReadyForReading: eventList[i].data.ptr]; |
︙ | ︙ |
Modified src/OFFile.h from [d4ed29ae4f] to [70f5f785c7].
1 | /* | < < | < | > < | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFSeekableStream.h" #import "OFKernelEventObserver.h" #ifndef OF_AMIGAOS # define OF_FILE_HANDLE_IS_FD typedef int OFFileHandle; static const OFFileHandle OFInvalidFileHandle = -1; #else typedef struct _OFFileHandle *OFFileHandle; static const OFFileHandle OFInvalidFileHandle = NULL; #endif OF_ASSUME_NONNULL_BEGIN @class OFURL; /** * @class OFFile OFFile.h ObjFW/OFFile.h * * @brief A class which provides methods to read and write files. */ OF_SUBCLASSING_RESTRICTED @interface OFFile: OFSeekableStream #ifdef OF_FILE_HANDLE_IS_FD <OFReadyForReadingObserving, OFReadyForWritingObserving> #endif { OFFileHandle _handle; bool _atEndOfStream; } /** * @brief Creates a new OFFile with the specified path and mode. * * @param path The path to the file to open as a string |
︙ | ︙ | |||
61 62 63 64 65 66 67 | * `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 */ | | < < < < < < < < < < < < < < < < < < < < < < | < < | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | * `wx` | Write-only, create or fail, exclusive * `w+` | Read-write, create or truncate * `w+x` | Read-write, create or fail, exclusive * `a` | Write-only, create or append * `a+` | Read-write, create or append * @return A new autoreleased OFFile */ + (instancetype)fileWithPath: (OFString *)path mode: (OFString *)mode; /** * @brief Creates a new OFFile with the specified native file handle. * * @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this * is a file descriptor. The handle is closed when the OFFile * object is deallocated! * @return A new autoreleased OFFile */ + (instancetype)fileWithHandle: (OFFileHandle)handle; /** * @brief Initializes an already allocated OFFile. * * @param path The path to the file to open as a string * @param mode The mode in which the file should be opened.@n * Possible modes are: |
︙ | ︙ | |||
119 120 121 122 123 124 125 | * `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 */ | | < < < < < < < < < < < < < < < < < < < < < < < < < < | | > | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | * `wb+` or `w+b` | read-write, create, truncate, binary * `a` | write-only, create, append * `ab` | write-only, create, append, binary * `a+` | read-write, create, append * `ab+` or `a+b` | read-write, create, append, binary * @return An initialized OFFile */ - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode; /** * @brief Initializes an already allocated OFFile. * * @param handle A native file handle. If OF_FILE_HANDLE_IS_FD is defined, this * 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 |
Modified src/OFFile.m from [211e9ba002] to [0786a18c44].
1 | /* | < < | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #define _LARGEFILE64_SOURCE #include <assert.h> #include <errno.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif |
︙ | ︙ | |||
75 76 77 78 79 80 81 | #ifndef O_EXLOCK # define O_EXLOCK 0 #endif #ifndef OF_AMIGAOS # define closeHandle(h) close(h) #else | | | | > > > > | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | #ifndef O_EXLOCK # define O_EXLOCK 0 #endif #ifndef OF_AMIGAOS # define closeHandle(h) close(h) #else static struct _OFFileHandle { struct _OFFileHandle *previous, *next; BPTR handle; bool append; } *firstHandle = NULL; static void closeHandle(OFFileHandle handle) { Close(handle->handle); Forbid(); if (handle->previous != NULL) handle->previous->next = handle->next; if (handle->next != NULL) handle->next->previous = handle->previous; if (firstHandle == handle) firstHandle = handle->next; Permit(); OFFreeMemory(handle); } OF_DESTRUCTOR() { for (OFFileHandle iter = firstHandle; iter != NULL; iter = iter->next) Close(iter->handle); } #endif #ifndef OF_AMIGAOS static int |
︙ | ︙ | |||
178 179 180 181 182 183 184 | #ifdef OF_NINTENDO_DS if (!nitroFSInit(NULL)) @throw [OFInitializationFailedException exceptionWithClass: self]; #endif } | | < | < < < < < < < < | < < < < < | < | | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | #ifdef OF_NINTENDO_DS if (!nitroFSInit(NULL)) @throw [OFInitializationFailedException exceptionWithClass: self]; #endif } + (instancetype)fileWithPath: (OFString *)path mode: (OFString *)mode { return [[[self alloc] initWithPath: path mode: mode] autorelease]; } + (instancetype)fileWithHandle: (OFFileHandle)handle { return [[[self alloc] initWithHandle: handle] autorelease]; } - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode { OFFileHandle handle; @try { void *pool = objc_autoreleasePoolPush(); int flags; #ifndef OF_AMIGAOS if ((flags = parseMode(mode.UTF8String)) == -1) |
︙ | ︙ | |||
239 240 241 242 243 244 245 | if (handle == -1) @throw [OFOpenItemFailedException exceptionWithPath: path mode: mode errNo: errno]; #else | | | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | if (handle == -1) @throw [OFOpenItemFailedException exceptionWithPath: path mode: mode errNo: errno]; #else handle = OFAllocMemory(1, sizeof(*handle)); @try { if ((flags = parseMode(mode.UTF8String, &handle->append)) == -1) @throw [OFInvalidArgumentException exception]; if ((handle->handle = Open([path cStringWithEncoding: [OFLocale encoding]], flags)) == 0) { |
︙ | ︙ | |||
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | Close(handle->handle); @throw [OFOpenItemFailedException exceptionWithPath: path mode: mode errNo: EIO]; } } handle->previous = NULL; handle->next = firstHandle; if (firstHandle != NULL) firstHandle->previous = handle; firstHandle = handle; } @catch (id e) { | > > > > | < < < < < < < < < < < < < < < < < < < < < | > > > > > | | < | | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | Close(handle->handle); @throw [OFOpenItemFailedException exceptionWithPath: path mode: mode errNo: EIO]; } } Forbid(); handle->previous = NULL; handle->next = firstHandle; if (firstHandle != NULL) firstHandle->previous = handle; firstHandle = handle; Permit(); } @catch (id e) { OFFreeMemory(handle); @throw e; } #endif objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } @try { self = [self initWithHandle: handle]; } @catch (id e) { closeHandle(handle); @throw e; } 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]; return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { ssize_t ret; if (_handle == OFInvalidFileHandle) @throw [OFNotOpenException exceptionWithObject: self]; #if defined(OF_WINDOWS) if (length > UINT_MAX) @throw [OFOutOfRangeException exception]; if ((ret = read(_handle, buffer, (unsigned int)length)) < 0) |
︙ | ︙ | |||
397 398 399 400 401 402 403 | if (ret == 0) _atEndOfStream = true; return ret; } | | < | | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | if (ret == 0) _atEndOfStream = true; return ret; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { if (_handle == OFInvalidFileHandle) @throw [OFNotOpenException exceptionWithObject: self]; #if defined(OF_WINDOWS) int bytesWritten; if (length > INT_MAX) @throw [OFOutOfRangeException exception]; |
︙ | ︙ | |||
456 457 458 459 460 461 462 | bytesWritten: 0 errNo: errno]; #endif return (size_t)bytesWritten; } | < | | | | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 | bytesWritten: 0 errNo: errno]; #endif return (size_t)bytesWritten; } - (OFFileOffset)lowlevelSeekToOffset: (OFFileOffset)offset whence: (int)whence { OFFileOffset ret; if (_handle == OFInvalidFileHandle) @throw [OFNotOpenException exceptionWithObject: self]; #ifndef OF_AMIGAOS # if defined(OF_WINDOWS) ret = _lseeki64(_handle, offset, whence); # elif defined(HAVE_LSEEK64) ret = lseek64(_handle, offset, whence); |
︙ | ︙ | |||
531 532 533 534 535 536 537 | { return _handle; } #endif - (void)close { | | | | | 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | { return _handle; } #endif - (void)close { if (_handle == OFInvalidFileHandle) @throw [OFNotOpenException exceptionWithObject: self]; closeHandle(_handle); _handle = OFInvalidFileHandle; [super close]; } - (void)dealloc { if (_handle != OFInvalidFileHandle) [self close]; [super dealloc]; } @end |
Modified src/OFFileManager.h from [f8bf172385] to [e259c02d73].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
44 45 46 47 48 49 50 | @class OFURL; /** * @brief A key for a file attribute in the file attributes dictionary. * * Possible keys for file URLs are: * | | | | | | | | | | | | | | | | | | > | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | > | > > > > > > > > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | @class OFURL; /** * @brief A key for a file attribute in the file attributes dictionary. * * Possible keys for file URLs are: * * * @ref OFFileSize * * @ref OFFileType * * @ref OFFilePOSIXPermissions * * @ref OFFileOwnerAccountID * * @ref OFFileGroupOwnerAccountID * * @ref OFFileOwnerAccountName * * @ref OFFileGroupOwnerAccountName * * @ref OFFileLastAccessDate * * @ref OFFileModificationDate * * @ref OFFileStatusChangeDate * * @ref OFFileCreationDate * * @ref OFFileSymbolicLinkDestination * * Other URL schemes might not have all keys and might have keys not listed. */ typedef OFConstantString *OFFileAttributeKey; /** * @brief The type of a file. * * Possibles values for file URLs are: * * * @ref OFFileTypeRegular * * @ref OFFileTypeDirectory * * @ref OFFileTypeSymbolicLink * * @ref OFFileTypeFIFO * * @ref OFFileTypeCharacterSpecial * * @ref OFFileTypeBlockSpecial * * @ref OFFileTypeSocket * * @ref OFFileTypeUnknown * * Other URL schemes might not have all types and might have types not listed. */ typedef OFConstantString *OFFileAttributeType; /** * @brief A dictionary mapping keys of type @ref OFFileAttributeKey to their * attribute values. */ typedef OFDictionary OF_GENERIC(OFFileAttributeKey, id) *OFFileAttributes; /** * @brief A mutable dictionary mapping keys of type @ref OFFileAttributeKey to * their attribute values. */ typedef OFMutableDictionary OF_GENERIC(OFFileAttributeKey, id) *OFMutableFileAttributes; #ifdef __cplusplus extern "C" { #endif /** * @brief The size of the file as an @ref OFNumber. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileSize. */ extern const OFFileAttributeKey OFFileSize; /** * @brief The type of the file. * * The corresponding value is of type @ref OFFileAttributeType. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileType. */ extern const OFFileAttributeKey OFFileType; /** * @brief The POSIX permissions of the file as an @ref OFNumber. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#filePOSIXPermissions. */ extern const OFFileAttributeKey OFFilePOSIXPermissions; /** * @brief The account ID of the owner of the file as an @ref OFNumber. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileOwnerAccountID. */ extern const OFFileAttributeKey OFFileOwnerAccountID; /** * @brief The account ID of the group owner of the file as an @ref OFNumber. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileGroupOwnerAccountID. */ extern const OFFileAttributeKey OFFileGroupOwnerAccountID; /** * @brief The account name of the owner of the file as an OFString. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileOwnerAccountName. */ extern const OFFileAttributeKey OFFileOwnerAccountName; /** * @brief The account name of the group owner of the file as an OFString. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileGroupOwnerAccountName. */ extern const OFFileAttributeKey OFFileGroupOwnerAccountName; /** * @brief The last access date of the file as an @ref OFDate. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileLastAccessDate. */ extern const OFFileAttributeKey OFFileLastAccessDate; /** * @brief The last modification date of the file as an @ref OFDate. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileModificationDate. */ extern const OFFileAttributeKey OFFileModificationDate; /** * @brief The last status change date of the file as an @ref OFDate. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileStatusChangeDate. */ extern const OFFileAttributeKey OFFileStatusChangeDate; /** * @brief The creation date of the file as an @ref OFDate. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileCreationDate. */ extern const OFFileAttributeKey OFFileCreationDate; /** * @brief The destination of a symbolic link as an OFString. * * For convenience, a category on @ref OFDictionary is provided to access this * via @ref OFDictionary#fileSymbolicLinkDestination. */ extern const OFFileAttributeKey OFFileSymbolicLinkDestination; /** * @brief A regular file. */ extern const OFFileAttributeType OFFileTypeRegular; /** * @brief A directory. */ extern const OFFileAttributeType OFFileTypeDirectory; /** * @brief A symbolic link. */ extern const OFFileAttributeType OFFileTypeSymbolicLink; /** * @brief A FIFO. */ extern const OFFileAttributeType OFFileTypeFIFO; /** * @brief A character special file. */ extern const OFFileAttributeType OFFileTypeCharacterSpecial; /** * @brief A block special file. */ extern const OFFileAttributeType OFFileTypeBlockSpecial; /** * @brief A socket. */ extern const OFFileAttributeType OFFileTypeSocket; /** * @brief An unknown file type. * * This is different from not having an @ref OFFileType at all in that it means * that retrieving file types is supported, but the particular file type is * unknown. */ extern const OFFileAttributeType OFFileTypeUnknown; #ifdef __cplusplus } #endif /** * @class OFFileManager OFFileManager.h ObjFW/OFFileManager.h * |
︙ | ︙ | |||
269 270 271 272 273 274 275 | #ifdef OF_HAVE_FILES /** * @brief Returns the attributes for the item at the specified path. * * @param path The path to return the attributes for * @return A dictionary of attributes for the specified path, with the keys of | | | | | | < | | 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | #ifdef OF_HAVE_FILES /** * @brief Returns the attributes for the item at the specified path. * * @param path The path to return the attributes for * @return A dictionary of attributes for the specified path, with the keys of * type @ref OFFileAttributeKey */ - (OFFileAttributes)attributesOfItemAtPath: (OFString *)path; #endif /** * @brief Returns the attributes for the item at the specified URL. * * @param URL The URL to return the attributes for * @return A dictionary of attributes for the specified URL, with the keys of * type @ref OFFileAttributeKey */ - (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL; #ifdef OF_HAVE_FILES /** * @brief Sets the attributes for the item at the specified path. * * All attributes not part of the dictionary are left unchanged. * * @param attributes The attributes to set for the specified path * @param path The path of the item to set the attributes for */ - (void)setAttributes: (OFFileAttributes)attributes ofItemAtPath: (OFString *)path; #endif /** * @brief Sets the attributes for the item at the specified URL. * * All attributes not part of the dictionary are left unchanged. * * @param attributes The attributes to set for the specified URL * @param URL The URL of the item to set the attributes for */ - (void)setAttributes: (OFFileAttributes)attributes ofItemAtURL: (OFURL *)URL; #ifdef OF_HAVE_FILES /** * @brief Checks whether a file exists at the specified path. * * @param path The path to check * @return A boolean whether there is a file at the specified path |
︙ | ︙ | |||
374 375 376 377 378 379 380 | /** * @brief Creates a directory at the specified URL. * * @param URL The URL of the directory to create * @param createParents Whether to create the parents of the directory */ | | < | > | | > > > > > > > > > > > | 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | /** * @brief Creates a directory at the specified URL. * * @param URL The URL of the directory to create * @param createParents Whether to create the parents of the directory */ - (void)createDirectoryAtURL: (OFURL *)URL createParents: (bool)createParents; #ifdef OF_HAVE_FILES /** * @brief Returns an array with the items in the specified directory. * * @note `.` and `..` are not part of the returned array. * * @param path The path to the directory whose items should be returned * @return An array of OFString with the items in the specified directory */ - (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtPath: (OFString *)path; #endif /** * @brief Returns an array with the URLs of the items in the specified * directory. * * @note `.` and `..` are not part of the returned array. * * @param URL The URL to the directory whose items should be returned * @return An array with the URLs of the items in the specified directory */ - (OFArray OF_GENERIC(OFURL *) *)contentsOfDirectoryAtURL: (OFURL *)URL; #ifdef OF_HAVE_FILES /** * @brief Returns an array with all subpaths of the specified directory. * * @note `.` and `..` (of the directory itself or any subdirectory) are not * part of the returned array. * * @param path The path to the directory whose subpaths should be returned * @return An array of OFString with the subpaths of the specified directory */ - (OFArray OF_GENERIC(OFString *) *)subpathsOfDirectoryAtPath: (OFString *)path; /** * @brief Changes the current working directory. * * @param path The new directory to change to */ - (void)changeCurrentDirectoryPath: (OFString *)path; |
︙ | ︙ | |||
427 428 429 430 431 432 433 | * If an item already exists, the copy operation fails. This is also the case * if a directory is copied and an item already exists in the destination * directory. * * @param source The file, directory or symbolic link to copy * @param destination The destination path */ | | < | < | < | < | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | * If an item already exists, the copy operation fails. This is also the case * if a directory is copied and an item already exists in the destination * directory. * * @param source The file, directory or symbolic link to copy * @param destination The destination path */ - (void)copyItemAtPath: (OFString *)source toPath: (OFString *)destination; #endif /** * @brief Copies a file, directory or symbolic link (if supported by the OS). * * The destination URL must have a full path, which means it must include the * name of the item. * * If an item already exists, the copy operation fails. This is also the case * if a directory is copied and an item already exists in the destination * directory. * * @param source The file, directory or symbolic link to copy * @param destination The destination URL */ - (void)copyItemAtURL: (OFURL *)source toURL: (OFURL *)destination; #ifdef OF_HAVE_FILES /** * @brief Moves an item. * * The destination path must be a full path, which means it must include the * name of the item. * * If the destination is on a different logical device, the source will be * copied to the destination using @ref copyItemAtPath:toPath: and the source * removed using @ref removeItemAtPath:. * * @param source The item to rename * @param destination The new name for the item */ - (void)moveItemAtPath: (OFString *)source toPath: (OFString *)destination; #endif /** * @brief Moves an item. * * The destination URL must have a full path, which means it must include the * name of the item. * * If the destination is on a different logical device or uses a different * scheme, the source will be copied to the destination using * @ref copyItemAtURL:toURL: and the source removed using @ref removeItemAtURL:. * * @param source The item to rename * @param destination The new name for the item */ - (void)moveItemAtURL: (OFURL *)source toURL: (OFURL *)destination; #ifdef OF_HAVE_FILES /** * @brief Removes the item at the specified path. * * If the item at the specified path is a directory, it is removed recursively. * |
︙ | ︙ | |||
513 514 515 516 517 518 519 | * name of the item. * * This method is not available on some systems. * * @param source The path to the item for which a link should be created * @param destination The path to the item which should link to the source */ | | < | < | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 | * name of the item. * * This method is not available on some systems. * * @param source The path to the item for which a link should be created * @param destination The path to the item which should link to the source */ - (void)linkItemAtPath: (OFString *)source toPath: (OFString *)destination; #endif /** * @brief Creates a hard link for the specified item. * * The destination URL must have a full path, which means it must include the * name of the item. * * This method is not available for all URLs. * * @param source The URL to the item for which a link should be created * @param destination The URL to the item which should link to the source */ - (void)linkItemAtURL: (OFURL *)source toURL: (OFURL *)destination; #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS /** * @brief Creates a symbolic link for an item. * * The destination path must be a full path, which means it must include the * name of the item. |
︙ | ︙ | |||
570 571 572 573 574 575 576 | */ - (void)createSymbolicLinkAtURL: (OFURL *)URL withDestinationPath: (OFString *)target; @end @interface OFDictionary (FileAttributes) /** | | | | | < | | | | | | | | < | < | < | | | < | 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 | */ - (void)createSymbolicLinkAtURL: (OFURL *)URL withDestinationPath: (OFString *)target; @end @interface OFDictionary (FileAttributes) /** * @brief The @ref OFFileSize key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) unsigned long long fileSize; /** * @brief The @ref OFFileType key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFFileAttributeType fileType; /** * @brief The @ref OFFilePOSIXPermissions key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) unsigned long filePOSIXPermissions; /** * @brief The @ref OFFileOwnerAccountID key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) unsigned long fileOwnerAccountID; /** * @brief The @ref OFFileGroupOwnerAccountID key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) unsigned long fileGroupOwnerAccountID; /** * @brief The @ref OFFileOwnerAccountName key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFString *fileOwnerAccountName; /** * @brief The @ref OFFileGroupOwnerAccountName key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFString *fileGroupOwnerAccountName; /** * @brief The @ref OFFileLastAccessDate key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFDate *fileLastAccessDate; /** * @brief The @ref OFFileModificationDate key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFDate *fileModificationDate; /** * @brief The @ref OFFileStatusChangeDate key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFDate *fileStatusChangeDate; /** * @brief The @ref OFFileCreationDate key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFDate *fileCreationDate; /** * @brief The @ref OFFileSymbolicLinkDestination key from the dictionary. * * Raises an @ref OFUndefinedKeyException if the key is missing. */ @property (readonly, nonatomic) OFString *fileSymbolicLinkDestination; @end OF_ASSUME_NONNULL_END |
Modified src/OFFileManager.m from [356e95e601] to [8b48822fc3].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
65 66 67 68 69 70 71 72 | # include <ntdef.h> #endif #ifdef OF_AMIGAOS # include <proto/exec.h> # include <proto/dos.h> #endif | | > | < | < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < > > | < | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | # include <ntdef.h> #endif #ifdef OF_AMIGAOS # include <proto/exec.h> # include <proto/dos.h> #endif #ifdef OF_MINT # include <bits/local_lim.h> #endif @interface OFDefaultFileManager: OFFileManager @end #ifdef OF_AMIGAOS4 # define CurrentDir(lock) SetCurrentDir(lock) #endif #include "OFFileManagerConstants.inc" static OFFileManager *defaultManager; #ifdef OF_AMIGAOS static bool dirChanged = false; static BPTR originalDirLock = 0; OF_DESTRUCTOR() { if (dirChanged) UnLock(CurrentDir(originalDirLock)); } #endif static id attributeForKeyOrException(OFFileAttributes attributes, OFFileAttributeKey key) { id object = [attributes objectForKey: key]; if (object == nil) @throw [OFUndefinedKeyException exceptionWithObject: attributes key: key]; |
︙ | ︙ | |||
229 230 231 232 233 234 235 | [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } #endif | | | | < | | < | < < | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } #endif - (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL { OFURLHandler *URLHandler; if (URL == nil) @throw [OFInvalidArgumentException exception]; if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; return [URLHandler attributesOfItemAtURL: URL]; } #ifdef OF_HAVE_FILES - (OFFileAttributes)attributesOfItemAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFFileAttributes ret; ret = [self attributesOfItemAtURL: [OFURL fileURLWithPath: path]]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } #endif - (void)setAttributes: (OFFileAttributes)attributes ofItemAtURL: (OFURL *)URL { OFURLHandler *URLHandler; if (URL == nil) @throw [OFInvalidArgumentException exception]; if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; [URLHandler setAttributes: attributes ofItemAtURL: URL]; } #ifdef OF_HAVE_FILES - (void)setAttributes: (OFFileAttributes)attributes ofItemAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); [self setAttributes: attributes ofItemAtURL: [OFURL fileURLWithPath: path]]; objc_autoreleasePoolPop(pool); } #endif - (bool)fileExistsAtURL: (OFURL *)URL { OFURLHandler *URLHandler; |
︙ | ︙ | |||
457 458 459 460 461 462 463 | [self createDirectoryAtURL: [OFURL fileURLWithPath: path] createParents: createParents]; objc_autoreleasePoolPop(pool); } #endif | | | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | [self createDirectoryAtURL: [OFURL fileURLWithPath: path] createParents: createParents]; objc_autoreleasePoolPop(pool); } #endif - (OFArray OF_GENERIC(OFURL *) *)contentsOfDirectoryAtURL: (OFURL *)URL { OFURLHandler *URLHandler; if (URL == nil) @throw [OFInvalidArgumentException exception]; if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; return [URLHandler contentsOfDirectoryAtURL: URL]; } #ifdef OF_HAVE_FILES - (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFURL *) *URLs; OFMutableArray OF_GENERIC(OFString *) *ret; URLs = [self contentsOfDirectoryAtURL: [OFURL fileURLWithPath: path]]; ret = [OFMutableArray arrayWithCapacity: URLs.count]; for (OFURL *URL in URLs) [ret addObject: URL.lastPathComponent]; [ret makeImmutable]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFArray OF_GENERIC(OFString *) *)subpathsOfDirectoryAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFMutableArray OF_GENERIC(OFString *) *ret = [OFMutableArray arrayWithObject: path]; for (OFString *subpath in [self contentsOfDirectoryAtPath: path]) { void *pool2 = objc_autoreleasePoolPush(); OFString *fullSubpath = [path stringByAppendingPathComponent: subpath]; OFFileAttributes attributes = [self attributesOfItemAtPath: fullSubpath]; if ([attributes.fileType isEqual: OFFileTypeDirectory]) [ret addObjectsFromArray: [self subpathsOfDirectoryAtPath: fullSubpath]]; else [ret addObject: fullSubpath]; objc_autoreleasePoolPop(pool2); } [ret makeImmutable]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } |
︙ | ︙ | |||
550 551 552 553 554 555 556 | void *pool = objc_autoreleasePoolPush(); [self changeCurrentDirectoryPath: URL.fileSystemRepresentation]; objc_autoreleasePoolPop(pool); } | | < | < | | | < | | | < | | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 | void *pool = objc_autoreleasePoolPush(); [self changeCurrentDirectoryPath: URL.fileSystemRepresentation]; objc_autoreleasePoolPop(pool); } - (void)copyItemAtPath: (OFString *)source toPath: (OFString *)destination { void *pool = objc_autoreleasePoolPush(); [self copyItemAtURL: [OFURL fileURLWithPath: source] toURL: [OFURL fileURLWithPath: destination]]; objc_autoreleasePoolPop(pool); } #endif - (void)copyItemAtURL: (OFURL *)source toURL: (OFURL *)destination { void *pool; OFURLHandler *URLHandler; OFFileAttributes attributes; OFFileAttributeType type; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); if ((URLHandler = [OFURLHandler handlerForURL: source]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: source]; if ([URLHandler copyItemAtURL: source toURL: destination]) return; if ([self fileExistsAtURL: destination]) @throw [OFCopyItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: EEXIST]; @try { attributes = [self attributesOfItemAtURL: source]; } @catch (OFRetrieveItemAttributesFailedException *e) { @throw [OFCopyItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: e.errNo]; } type = attributes.fileType; if ([type isEqual: OFFileTypeDirectory]) { OFArray OF_GENERIC(OFURL *) *contents; @try { [self createDirectoryAtURL: destination]; @try { OFFileAttributeKey key = OFFilePOSIXPermissions; OFNumber *permissions = [attributes objectForKey: key]; OFFileAttributes destinationAttributes; if (permissions != nil) { destinationAttributes = [OFDictionary dictionaryWithObject: permissions forKey: key]; [self setAttributes: destinationAttributes |
︙ | ︙ | |||
641 642 643 644 645 646 647 | exceptionWithSourceURL: source destinationURL: destination errNo: [e errNo]]; @throw e; } | | | < < | < | | < | | | < | | 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | exceptionWithSourceURL: source destinationURL: destination errNo: [e errNo]]; @throw e; } for (OFURL *item in contents) { void *pool2 = objc_autoreleasePoolPush(); OFURL *destinationURL = [destination URLByAppendingPathComponent: item.lastPathComponent]; [self copyItemAtURL: item toURL: destinationURL]; objc_autoreleasePoolPop(pool2); } } else if ([type isEqual: OFFileTypeRegular]) { size_t pageSize = [OFSystemInfo pageSize]; OFStream *sourceStream = nil; OFStream *destinationStream = nil; char *buffer; buffer = OFAllocMemory(1, pageSize); @try { sourceStream = [[OFURLHandler handlerForURL: source] openItemAtURL: source mode: @"r"]; destinationStream = [[OFURLHandler handlerForURL: destination] openItemAtURL: destination mode: @"w"]; while (!sourceStream.atEndOfStream) { size_t length; length = [sourceStream readIntoBuffer: buffer length: pageSize]; [destinationStream writeBuffer: buffer length: length]; } @try { OFFileAttributeKey key = OFFilePOSIXPermissions; OFNumber *permissions = [attributes objectForKey: key]; OFFileAttributes destinationAttributes; if (permissions != nil) { destinationAttributes = [OFDictionary dictionaryWithObject: permissions forKey: key]; [self setAttributes: destinationAttributes |
︙ | ︙ | |||
714 715 716 717 718 719 720 | destinationURL: destination errNo: [e errNo]]; @throw e; } @finally { [sourceStream close]; [destinationStream close]; | | | | 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 | destinationURL: destination errNo: [e errNo]]; @throw e; } @finally { [sourceStream close]; [destinationStream close]; OFFreeMemory(buffer); } } else if ([type isEqual: OFFileTypeSymbolicLink]) { @try { OFString *linkDestination = attributes.fileSymbolicLinkDestination; [self createSymbolicLinkAtURL: destination withDestinationPath: linkDestination]; } @catch (id e) { |
︙ | ︙ | |||
748 749 750 751 752 753 754 | destinationURL: destination errNo: EINVAL]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_FILES | | < < < | < | < | < | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | destinationURL: destination errNo: EINVAL]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_FILES - (void)moveItemAtPath: (OFString *)source toPath: (OFString *)destination { void *pool = objc_autoreleasePoolPush(); [self moveItemAtURL: [OFURL fileURLWithPath: source] toURL: [OFURL fileURLWithPath: destination]]; objc_autoreleasePoolPop(pool); } #endif - (void)moveItemAtURL: (OFURL *)source toURL: (OFURL *)destination { void *pool; OFURLHandler *URLHandler; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); if ((URLHandler = [OFURLHandler handlerForURL: source]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: source]; @try { if ([URLHandler moveItemAtURL: source toURL: destination]) return; } @catch (OFMoveItemFailedException *e) { if (e.errNo != EXDEV) @throw e; } if ([self fileExistsAtURL: destination]) @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: EEXIST]; @try { [self copyItemAtURL: source toURL: destination]; } @catch (OFCopyItemFailedException *e) { [self removeItemAtURL: destination]; @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: e.errNo]; |
︙ | ︙ | |||
831 832 833 834 835 836 837 | [URLHandler removeItemAtURL: URL]; } #ifdef OF_HAVE_FILES - (void)removeItemAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); | < < | < | < | < < < | < < < | 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 | [URLHandler removeItemAtURL: URL]; } #ifdef OF_HAVE_FILES - (void)removeItemAtPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); [self removeItemAtURL: [OFURL fileURLWithPath: path]]; objc_autoreleasePoolPop(pool); } #endif - (void)linkItemAtURL: (OFURL *)source toURL: (OFURL *)destination { void *pool = objc_autoreleasePoolPush(); OFURLHandler *URLHandler; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; if (![destination.scheme isEqual: source.scheme]) @throw [OFInvalidArgumentException exception]; URLHandler = [OFURLHandler handlerForURL: source]; if (URLHandler == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: source]; [URLHandler linkItemAtURL: source toURL: destination]; objc_autoreleasePoolPop(pool); } #ifdef OF_FILE_MANAGER_SUPPORTS_LINKS - (void)linkItemAtPath: (OFString *)source toPath: (OFString *)destination { void *pool = objc_autoreleasePoolPush(); [self linkItemAtURL: [OFURL fileURLWithPath: source] toURL: [OFURL fileURLWithPath: destination]]; objc_autoreleasePoolPop(pool); } #endif - (void)createSymbolicLinkAtURL: (OFURL *)URL withDestinationPath: (OFString *)target { void *pool = objc_autoreleasePoolPush(); OFURLHandler *URLHandler; if (URL == nil || target == nil) @throw [OFInvalidArgumentException exception]; URLHandler = [OFURLHandler handlerForURL: URL]; if (URLHandler == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; [URLHandler createSymbolicLinkAtURL: URL withDestinationPath: target]; objc_autoreleasePoolPop(pool); } #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS - (void)createSymbolicLinkAtPath: (OFString *)path withDestinationPath: (OFString *)target { void *pool = objc_autoreleasePoolPush(); [self createSymbolicLinkAtURL: [OFURL fileURLWithPath: path] withDestinationPath: target]; objc_autoreleasePoolPop(pool); } #endif @end @implementation OFDefaultFileManager - (instancetype)autorelease |
︙ | ︙ | |||
926 927 928 929 930 931 932 | - (void)release { } - (unsigned int)retainCount { | | | | | | | | | | | | | | | < | < | < | < | < | 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 | - (void)release { } - (unsigned int)retainCount { return OFMaxRetainCount; } @end @implementation OFDictionary (FileAttributes) - (unsigned long long)fileSize { return [attributeForKeyOrException(self, OFFileSize) unsignedLongLongValue]; } - (OFFileAttributeType)fileType { return attributeForKeyOrException(self, OFFileType); } - (unsigned long)filePOSIXPermissions { return [attributeForKeyOrException(self, OFFilePOSIXPermissions) unsignedLongValue]; } - (unsigned long)fileOwnerAccountID { return [attributeForKeyOrException(self, OFFileOwnerAccountID) unsignedLongValue]; } - (unsigned long)fileGroupOwnerAccountID { return [attributeForKeyOrException(self, OFFileGroupOwnerAccountID) unsignedLongValue]; } - (OFString *)fileOwnerAccountName { return attributeForKeyOrException(self, OFFileOwnerAccountName); } - (OFString *)fileGroupOwnerAccountName { return attributeForKeyOrException(self, OFFileGroupOwnerAccountName); } - (OFDate *)fileLastAccessDate { return attributeForKeyOrException(self, OFFileLastAccessDate); } - (OFDate *)fileModificationDate { return attributeForKeyOrException(self, OFFileModificationDate); } - (OFDate *)fileStatusChangeDate { return attributeForKeyOrException(self, OFFileStatusChangeDate); } - (OFDate *)fileCreationDate { return attributeForKeyOrException(self, OFFileCreationDate); } - (OFString *)fileSymbolicLinkDestination { return attributeForKeyOrException(self, OFFileSymbolicLinkDestination); } @end |
Added src/OFFileManagerConstants.inc version [7a3eb9bf4f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ const OFFileAttributeKey OFFileSize = @"OFFileSize"; const OFFileAttributeKey OFFileType = @"OFFileType"; const OFFileAttributeKey OFFilePOSIXPermissions = @"OFFilePOSIXPermissions"; const OFFileAttributeKey OFFileOwnerAccountID = @"OFFileOwnerAccountID"; const OFFileAttributeKey OFFileGroupOwnerAccountID = @"OFFileGroupOwnerAccountID"; const OFFileAttributeKey OFFileOwnerAccountName = @"OFFileOwnerAccountName"; const OFFileAttributeKey OFFileGroupOwnerAccountName = @"OFFileGroupOwnerAccountName"; const OFFileAttributeKey OFFileLastAccessDate = @"OFFileLastAccessDate"; const OFFileAttributeKey OFFileModificationDate = @"OFFileModificationDate"; const OFFileAttributeKey OFFileStatusChangeDate = @"OFFileStatusChangeDate"; const OFFileAttributeKey OFFileCreationDate = @"OFFileCreationDate"; const OFFileAttributeKey OFFileSymbolicLinkDestination = @"OFFileSymbolicLinkDestination"; const OFFileAttributeType OFFileTypeRegular = @"OFFileTypeRegular"; const OFFileAttributeType OFFileTypeDirectory = @"OFFileTypeDirectory"; const OFFileAttributeType OFFileTypeSymbolicLink = @"OFFileTypeSymbolicLink"; const OFFileAttributeType OFFileTypeFIFO = @"OFFileTypeFIFO"; const OFFileAttributeType OFFileTypeCharacterSpecial = @"OFFileTypeCharacterSpecial"; const OFFileAttributeType OFFileTypeBlockSpecial = @"OFFileTypeBlockSpecial"; const OFFileAttributeType OFFileTypeSocket = @"OFFileTypeSocket"; const OFFileAttributeType OFFileTypeUnknown = @"OFFileTypeUnknown"; |
Modified src/OFFileURLHandler.h from [8275bdd541] to [bc6fd1985b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFFileURLHandler.m from [987947edfd] to [50a5ea9a56].
1 | /* | < < | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #define _LARGEFILE64_SOURCE #include <errno.h> #include <math.h> #ifdef HAVE_DIRENT_H # include <dirent.h> #endif |
︙ | ︙ | |||
81 82 83 84 85 86 87 | # include <proto/dos.h> # include <proto/locale.h> # ifdef OF_AMIGAOS4 # define DeleteFile(path) Delete(path) # endif #endif | | | | | | | | > > > > > > > > > > > > | | | | | | < | < | < | | > | < < | | | < | < | < | < | < | < | < | < | < < | | | < | < | < | < | < | < | | | < | | | > | > < < | > > | < > > > > | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | # include <proto/dos.h> # include <proto/locale.h> # ifdef OF_AMIGAOS4 # define DeleteFile(path) Delete(path) # endif #endif #if defined(OF_WINDOWS) || defined(OF_AMIGAOS) typedef struct { OFFileOffset st_size; unsigned int st_mode; OFTimeInterval st_atime, st_mtime, st_ctime; # ifdef OF_WINDOWS # define HAVE_STRUCT_STAT_ST_BIRTHTIME OFTimeInterval st_birthtime; DWORD fileAttributes; # endif } Stat; #elif defined(HAVE_STAT64) typedef struct stat64 Stat; #else typedef struct stat Stat; #endif #ifdef OF_WINDOWS # define S_IFLNK 0x10000 # define S_ISLNK(mode) (mode & S_IFLNK) #endif #if defined(OF_FILE_MANAGER_SUPPORTS_OWNER) && defined(OF_HAVE_THREADS) static OFMutex *passwdMutex; static void releasePasswdMutex(void) { [passwdMutex release]; } #endif #if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) && !defined(OF_WINDOWS) static OFMutex *readdirMutex; static void releaseReaddirMutex(void) { [readdirMutex release]; } #endif #ifdef OF_WINDOWS static int (*_wutime64FuncPtr)(const wchar_t *, struct __utimbuf64 *); static WINAPI BOOLEAN (*createSymbolicLinkWFuncPtr)(LPCWSTR, LPCWSTR, DWORD); static WINAPI BOOLEAN (*createHardLinkWFuncPtr)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES); #endif #ifdef OF_WINDOWS static OFTimeInterval filetimeToTimeInterval(const FILETIME *filetime) { return (double)((int64_t)filetime->dwHighDateTime << 32 | filetime->dwLowDateTime) / 10000000.0 - 11644473600.0; } static int retrieveError(void) { switch (GetLastError()) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: case ERROR_NO_MORE_FILES: return ENOENT; case ERROR_ACCESS_DENIED: return EACCES; case ERROR_DIRECTORY: return ENOTDIR; case ERROR_NOT_READY: return EBUSY; default: return EIO; } } #endif #ifdef OF_AMIGAOS static int retrieveError(void) { switch (IoErr()) { case ERROR_DELETE_PROTECTED: case ERROR_READ_PROTECTED: case ERROR_WRITE_PROTECTED: return EACCES; case ERROR_DISK_NOT_VALIDATED: case ERROR_OBJECT_IN_USE: return EBUSY; case ERROR_OBJECT_EXISTS: return EEXIST; case ERROR_DIR_NOT_FOUND: case ERROR_NO_MORE_ENTRIES: case ERROR_OBJECT_NOT_FOUND: return ENOENT; case ERROR_NO_FREE_STORE: return ENOMEM; case ERROR_DISK_FULL: return ENOSPC; case ERROR_DIRECTORY_NOT_EMPTY: return ENOTEMPTY; case ERROR_DISK_WRITE_PROTECTED: return EROFS; case ERROR_RENAME_ACROSS_DEVICES: return EXDEV; default: return EIO; } } #endif static int statWrapper(OFString *path, Stat *buffer) { #if defined(OF_WINDOWS) WIN32_FILE_ATTRIBUTE_DATA data; bool success; if ([OFSystemInfo isWindowsNT]) success = GetFileAttributesExW(path.UTF16String, GetFileExInfoStandard, &data); else success = GetFileAttributesExA( [path cStringWithEncoding: [OFLocale encoding]], GetFileExInfoStandard, &data); if (!success) return retrieveError(); buffer->st_size = (uint64_t)data.nFileSizeHigh << 32 | data.nFileSizeLow; if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) buffer->st_mode = S_IFDIR; else if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { /* * No need to use A functions in this branch: This is only * available on NTFS (and hence Windows NT) anyway. */ WIN32_FIND_DATAW findData; HANDLE findHandle; if ((findHandle = FindFirstFileW(path.UTF16String, &findData)) == INVALID_HANDLE_VALUE) return retrieveError(); @try { if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) /* Race? Indicate to try again. */ return EAGAIN; buffer->st_mode = (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK ? S_IFLNK : S_IFREG); } @finally { FindClose(findHandle); } } else buffer->st_mode = S_IFREG; buffer->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? (S_IRUSR | S_IXUSR) : (S_IRUSR | S_IWUSR | S_IXUSR)); buffer->st_atime = filetimeToTimeInterval(&data.ftLastAccessTime); buffer->st_mtime = filetimeToTimeInterval(&data.ftLastWriteTime); buffer->st_ctime = buffer->st_birthtime = filetimeToTimeInterval(&data.ftCreationTime); buffer->fileAttributes = data.dwFileAttributes; return 0; #elif defined(OF_AMIGAOS) BPTR lock; # ifdef OF_AMIGAOS4 struct ExamineData *ed; # else struct FileInfoBlock fib; # endif OFTimeInterval timeInterval; struct Locale *locale; struct DateStamp *date; if ((lock = Lock([path cStringWithEncoding: [OFLocale encoding]], SHARED_LOCK)) == 0) return retrieveError(); # if defined(OF_MORPHOS) if (!Examine64(lock, &fib, TAG_DONE)) { # elif defined(OF_AMIGAOS4) if ((ed = ExamineObjectTags(EX_FileLockInput, lock, TAG_END)) == NULL) { # else if (!Examine(lock, &fib)) { # endif int error = retrieveError(); UnLock(lock); return error; } UnLock(lock); # if defined(OF_MORPHOS) buffer->st_size = fib.fib_Size64; # elif defined(OF_AMIGAOS4) buffer->st_size = ed->FileSize; # else buffer->st_size = fib.fib_Size; # endif # ifdef OF_AMIGAOS4 buffer->st_mode = (EXD_IS_DIRECTORY(ed) ? S_IFDIR : S_IFREG); # else buffer->st_mode = (fib.fib_DirEntryType > 0 ? S_IFDIR : S_IFREG); # endif timeInterval = 252460800; /* 1978-01-01 */ locale = OpenLocale(NULL); /* |
︙ | ︙ | |||
315 316 317 318 319 320 321 | # ifdef OF_AMIGAOS4 date = &ed->Date; # else date = &fib.fib_Date; # endif timeInterval += date->ds_Days * 86400.0; timeInterval += date->ds_Minute * 60.0; | | | > > > > | > > > | | > > | > > > | | | < | < | | | < | | | | | < > > | | | | | | < | | | | | | | < < | | | < | | | | < | > > | | | | | | < | | > | | | | | | | | < | | | 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 | # ifdef OF_AMIGAOS4 date = &ed->Date; # else date = &fib.fib_Date; # endif timeInterval += date->ds_Days * 86400.0; timeInterval += date->ds_Minute * 60.0; timeInterval += date->ds_Tick / (OFTimeInterval)TICKS_PER_SECOND; buffer->st_atime = buffer->st_mtime = buffer->st_ctime = timeInterval; # ifdef OF_AMIGAOS4 FreeDosObject(DOS_EXAMINEDATA, ed); # endif return 0; #elif defined(HAVE_STAT64) if (stat64([path cStringWithEncoding: [OFLocale encoding]], buffer) != 0) return errno; return 0; #else if (stat([path cStringWithEncoding: [OFLocale encoding]], buffer) != 0) return errno; return 0; #endif } static int lstatWrapper(OFString *path, Stat *buffer) { #if defined(HAVE_LSTAT) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS) && \ !defined(OF_NINTENDO_3DS) && !defined(OF_WII) # ifdef HAVE_LSTAT64 if (lstat64([path cStringWithEncoding: [OFLocale encoding]], buffer) != 0) return errno; # else if (lstat([path cStringWithEncoding: [OFLocale encoding]], buffer) != 0) return errno; # endif return 0; #else return statWrapper(path, buffer); #endif } static void setTypeAttribute(OFMutableFileAttributes attributes, Stat *s) { if (S_ISREG(s->st_mode)) [attributes setObject: OFFileTypeRegular forKey: OFFileType]; else if (S_ISDIR(s->st_mode)) [attributes setObject: OFFileTypeDirectory forKey: OFFileType]; #ifdef S_ISLNK else if (S_ISLNK(s->st_mode)) [attributes setObject: OFFileTypeSymbolicLink forKey: OFFileType]; #endif #ifdef S_ISFIFO else if (S_ISFIFO(s->st_mode)) [attributes setObject: OFFileTypeFIFO forKey: OFFileType]; #endif #ifdef S_ISCHR else if (S_ISCHR(s->st_mode)) [attributes setObject: OFFileTypeCharacterSpecial forKey: OFFileType]; #endif #ifdef S_ISBLK else if (S_ISBLK(s->st_mode)) [attributes setObject: OFFileTypeBlockSpecial forKey: OFFileType]; #endif #ifdef S_ISSOCK else if (S_ISSOCK(s->st_mode)) [attributes setObject: OFFileTypeSocket forKey: OFFileType]; #endif else [attributes setObject: OFFileTypeUnknown forKey: OFFileType]; } static void setDateAttributes(OFMutableFileAttributes attributes, Stat *s) { /* FIXME: We could be more precise on some OSes */ [attributes setObject: [OFDate dateWithTimeIntervalSince1970: s->st_atime] forKey: OFFileLastAccessDate]; [attributes setObject: [OFDate dateWithTimeIntervalSince1970: s->st_mtime] forKey: OFFileModificationDate]; [attributes setObject: [OFDate dateWithTimeIntervalSince1970: s->st_ctime] forKey: OFFileStatusChangeDate]; #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME [attributes setObject: [OFDate dateWithTimeIntervalSince1970: s->st_birthtime] forKey: OFFileCreationDate]; #endif } static void setOwnerAndGroupAttributes(OFMutableFileAttributes attributes, Stat *s) { #ifdef OF_FILE_MANAGER_SUPPORTS_OWNER [attributes setObject: [NSNumber numberWithUnsignedLong: s->st_uid] forKey: OFFileOwnerAccountID]; [attributes setObject: [NSNumber numberWithUnsignedLong: s->st_gid] forKey: OFFileGroupOwnerAccountID]; # ifdef OF_HAVE_THREADS [passwdMutex lock]; @try { # endif OFStringEncoding encoding = [OFLocale encoding]; struct passwd *passwd = getpwuid(s->st_uid); struct group *group_ = getgrgid(s->st_gid); if (passwd != NULL) { OFString *owner = [OFString stringWithCString: passwd->pw_name encoding: encoding]; [attributes setObject: owner forKey: OFFileOwnerAccountName]; } if (group_ != NULL) { OFString *group = [OFString stringWithCString: group_->gr_name encoding: encoding]; [attributes setObject: group forKey: OFFileGroupOwnerAccountName]; } # ifdef OF_HAVE_THREADS } @finally { [passwdMutex unlock]; } # endif #endif } #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS static void setSymbolicLinkDestinationAttribute(OFMutableFileAttributes attributes, OFURL *URL) { OFString *path = URL.fileSystemRepresentation; # ifndef OF_WINDOWS OFStringEncoding encoding = [OFLocale encoding]; char destinationC[PATH_MAX]; ssize_t length; OFString *destination; length = readlink([path cStringWithEncoding: encoding], destinationC, PATH_MAX); if (length < 0) @throw [OFRetrieveItemAttributesFailedException exceptionWithURL: URL errNo: errno]; destination = [OFString stringWithCString: destinationC encoding: encoding length: length]; [attributes setObject: destination forKey: OFFileSymbolicLinkDestination]; # else HANDLE handle; OFString *destination; if (createSymbolicLinkWFuncPtr == NULL) return; if ((handle = CreateFileW(path.UTF16String, 0, (FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL)) == INVALID_HANDLE_VALUE) @throw [OFRetrieveItemAttributesFailedException exceptionWithURL: URL errNo: retrieveError()]; @try { union { char bytes[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; REPARSE_DATA_BUFFER data; } buffer; DWORD size; wchar_t *tmp; if (!DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer.bytes, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &size, NULL)) @throw [OFRetrieveItemAttributesFailedException exceptionWithURL: URL errNo: retrieveError()]; if (buffer.data.ReparseTag != IO_REPARSE_TAG_SYMLINK) @throw [OFRetrieveItemAttributesFailedException exceptionWithURL: URL errNo: retrieveError()]; # define slrb buffer.data.SymbolicLinkReparseBuffer tmp = slrb.PathBuffer + (slrb.SubstituteNameOffset / sizeof(wchar_t)); destination = [OFString stringWithUTF16String: tmp length: slrb.SubstituteNameLength / sizeof(wchar_t)]; [attributes setObject: OFFileTypeSymbolicLink forKey: OFFileType]; [attributes setObject: destination forKey: OFFileSymbolicLinkDestination]; # undef slrb } @finally { CloseHandle(handle); } # endif } #endif @implementation OFFileURLHandler + (void)initialize { #ifdef OF_WINDOWS HMODULE module; #endif if (self != [OFFileURLHandler class]) return; #if defined(OF_FILE_MANAGER_SUPPORTS_OWNER) && defined(OF_HAVE_THREADS) passwdMutex = [[OFMutex alloc] init]; atexit(releasePasswdMutex); #endif #if !defined(HAVE_READDIR_R) && !defined(OF_WINDOWS) && defined(OF_HAVE_THREADS) readdirMutex = [[OFMutex alloc] init]; atexit(releaseReaddirMutex); #endif #ifdef OF_WINDOWS if ((module = LoadLibrary("msvcrt.dll")) != NULL) _wutime64FuncPtr = (int (*)(const wchar_t *, struct __utimbuf64 *))GetProcAddress(module, "_wutime64"); if ((module = LoadLibrary("kernel32.dll")) != NULL) { createSymbolicLinkWFuncPtr = (WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR, DWORD)) GetProcAddress(module, "CreateSymbolicLinkW"); createHardLinkWFuncPtr = (WINAPI BOOLEAN (*)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES)) GetProcAddress(module, "CreateHardLinkW"); } #endif /* * Make sure OFFile is initialized. * On some systems, this is needed to initialize the file system driver. */ [OFFile class]; } + (bool)of_directoryExistsAtPath: (OFString *)path { Stat s; if (statWrapper(path, &s) != 0) return false; return S_ISDIR(s.st_mode); } - (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode { void *pool = objc_autoreleasePoolPush(); OFFile *file = [[OFFile alloc] initWithPath: URL.fileSystemRepresentation mode: mode]; objc_autoreleasePoolPop(pool); return [file autorelease]; } - (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL { OFMutableFileAttributes ret = [OFMutableDictionary dictionary]; void *pool = objc_autoreleasePoolPush(); OFString *path; int error; Stat s; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![[URL scheme] isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; if ((error = lstatWrapper(path, &s)) != 0) @throw [OFRetrieveItemAttributesFailedException exceptionWithURL: URL errNo: error]; if (s.st_size < 0) @throw [OFOutOfRangeException exception]; [ret setObject: [NSNumber numberWithUnsignedLongLong: s.st_size] forKey: OFFileSize]; setTypeAttribute(ret, &s); [ret setObject: [NSNumber numberWithUnsignedLong: s.st_mode] forKey: OFFilePOSIXPermissions]; setOwnerAndGroupAttributes(ret, &s); setDateAttributes(ret, &s); #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS if (S_ISLNK(s.st_mode)) setSymbolicLinkDestinationAttribute(ret, URL); #endif objc_autoreleasePoolPop(pool); return ret; } - (void)of_setLastAccessDate: (OFDate *)lastAccessDate andModificationDate: (OFDate *)modificationDate ofItemAtURL: (OFURL *)URL attributes: (OFFileAttributes)attributes OF_DIRECT { OFString *path = URL.fileSystemRepresentation; OFFileAttributeKey attributeKey = (modificationDate != nil ? OFFileModificationDate : OFFileLastAccessDate); if (lastAccessDate == nil) lastAccessDate = modificationDate; if (modificationDate == nil) modificationDate = lastAccessDate; #if defined(OF_WINDOWS) if (_wutime64FuncPtr != NULL) { struct __utimbuf64 times = { .actime = (__time64_t)lastAccessDate.timeIntervalSince1970, .modtime = (__time64_t)modificationDate.timeIntervalSince1970 }; if (_wutime64FuncPtr([path UTF16String], ×) != 0) @throw [OFSetItemAttributesFailedException exceptionWithURL: URL attributes: attributes failedAttribute: attributeKey errNo: errno]; } else { struct _utimbuf times = { |
︙ | ︙ | |||
691 692 693 694 695 696 697 | exceptionWithURL: URL attributes: attributes failedAttribute: attributeKey errNo: errno]; } #elif defined(OF_AMIGAOS) /* AmigaOS does not support access time. */ | | | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 | exceptionWithURL: URL attributes: attributes failedAttribute: attributeKey errNo: errno]; } #elif defined(OF_AMIGAOS) /* AmigaOS does not support access time. */ OFTimeInterval modificationTime = modificationDate.timeIntervalSince1970; struct Locale *locale; struct DateStamp date; modificationTime -= 252460800; /* 1978-01-01 */ if (modificationTime < 0) |
︙ | ︙ | |||
714 715 716 717 718 719 720 | modificationTime -= locale->loc_GMTOffset * 60.0; CloseLocale(locale); date.ds_Days = modificationTime / 86400; date.ds_Minute = ((LONG)modificationTime % 86400) / 60; date.ds_Tick = fmod(modificationTime, 60) * TICKS_PER_SECOND; | > | | | | > > | < < | | | < | > | | | | | | | | | 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 | modificationTime -= locale->loc_GMTOffset * 60.0; CloseLocale(locale); date.ds_Days = modificationTime / 86400; date.ds_Minute = ((LONG)modificationTime % 86400) / 60; date.ds_Tick = fmod(modificationTime, 60) * TICKS_PER_SECOND; # ifdef OF_AMIGAOS4 if (!SetDate([path cStringWithEncoding: [OFLocale encoding]], &date) != 0) # else if (!SetFileDate([path cStringWithEncoding: [OFLocale encoding]], &date) != 0) # endif @throw [OFSetItemAttributesFailedException exceptionWithURL: URL attributes: attributes failedAttribute: attributeKey errNo: retrieveError()]; #else OFTimeInterval lastAccessTime = lastAccessDate.timeIntervalSince1970; OFTimeInterval modificationTime = modificationDate.timeIntervalSince1970; struct timeval times[2] = { { .tv_sec = (time_t)lastAccessTime, .tv_usec = (int)((lastAccessTime - times[0].tv_sec) * 1000000) }, { .tv_sec = (time_t)modificationTime, .tv_usec = (int)((modificationTime - times[1].tv_sec) * 1000000) }, }; if (utimes([path cStringWithEncoding: [OFLocale encoding]], times) != 0) @throw [OFSetItemAttributesFailedException exceptionWithURL: URL attributes: attributes failedAttribute: attributeKey errNo: errno]; #endif } - (void)of_setPOSIXPermissions: (OFNumber *)permissions ofItemAtURL: (OFURL *)URL attributes: (OFFileAttributes)attributes OF_DIRECT { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS mode_t mode = (mode_t)permissions.unsignedLongValue; OFString *path = URL.fileSystemRepresentation; int status; # ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) status = _wchmod(path.UTF16String, mode); else # endif status = chmod( [path cStringWithEncoding: [OFLocale encoding]], mode); if (status != 0) @throw [OFSetItemAttributesFailedException exceptionWithURL: URL attributes: attributes failedAttribute: OFFilePOSIXPermissions errNo: errno]; #else OF_UNRECOGNIZED_SELECTOR #endif } - (void)of_setOwnerAccountName: (OFString *)owner andGroupOwnerAccountName: (OFString *)group ofItemAtURL: (OFURL *)URL attributeKey: (OFFileAttributeKey)attributeKey attributes: (OFFileAttributes)attributes OF_DIRECT { #ifdef OF_FILE_MANAGER_SUPPORTS_OWNER OFString *path = URL.fileSystemRepresentation; uid_t uid = -1; gid_t gid = -1; OFStringEncoding encoding; if (owner == nil && group == nil) @throw [OFInvalidArgumentException exception]; encoding = [OFLocale encoding]; # ifdef OF_HAVE_THREADS |
︙ | ︙ | |||
844 845 846 847 848 849 850 | failedAttribute: attributeKey errNo: errno]; #else OF_UNRECOGNIZED_SELECTOR #endif } | < | | | | | | | | | | | | | | | | | | | < | < | | | | | 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 | failedAttribute: attributeKey errNo: errno]; #else OF_UNRECOGNIZED_SELECTOR #endif } - (void)setAttributes: (OFFileAttributes)attributes ofItemAtURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); OFEnumerator OF_GENERIC(OFFileAttributeKey) *keyEnumerator; OFEnumerator *objectEnumerator; OFFileAttributeKey key; id object; OFDate *lastAccessDate, *modificationDate; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; keyEnumerator = [attributes keyEnumerator]; objectEnumerator = [attributes objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { if ([key isEqual: OFFileModificationDate] || [key isEqual: OFFileLastAccessDate]) continue; else if ([key isEqual: OFFilePOSIXPermissions]) [self of_setPOSIXPermissions: object ofItemAtURL: URL attributes: attributes]; else if ([key isEqual: OFFileOwnerAccountName]) [self of_setOwnerAccountName: object andGroupOwnerAccountName: nil ofItemAtURL: URL attributeKey: key attributes: attributes]; else if ([key isEqual: OFFileGroupOwnerAccountName]) [self of_setOwnerAccountName: nil andGroupOwnerAccountName: object ofItemAtURL: URL attributeKey: key attributes: attributes]; else @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; } lastAccessDate = [attributes objectForKey: OFFileLastAccessDate]; modificationDate = [attributes objectForKey: OFFileModificationDate]; if (lastAccessDate != nil || modificationDate != nil) [self of_setLastAccessDate: lastAccessDate andModificationDate: modificationDate ofItemAtURL: URL attributes: attributes]; objc_autoreleasePoolPop(pool); } - (bool)fileExistsAtURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); Stat s; bool ret; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; if (statWrapper(URL.fileSystemRepresentation, &s) != 0) { objc_autoreleasePoolPop(pool); return false; } ret = S_ISREG(s.st_mode); objc_autoreleasePoolPop(pool); return ret; } - (bool)directoryExistsAtURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); Stat s; bool ret; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; if (statWrapper(URL.fileSystemRepresentation, &s) != 0) { objc_autoreleasePoolPop(pool); return false; } ret = S_ISDIR(s.st_mode); objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
982 983 984 985 986 987 988 | @throw [OFCreateDirectoryFailedException exceptionWithURL: URL errNo: errno]; #elif defined(OF_AMIGAOS) BPTR lock; if ((lock = CreateDir( | | < < | < | | | < < < < < | < | > | | | < < < < < | < | > | | | < < | > | | < | | > | < | > | | < | 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 | @throw [OFCreateDirectoryFailedException exceptionWithURL: URL errNo: errno]; #elif defined(OF_AMIGAOS) BPTR lock; if ((lock = CreateDir( [path cStringWithEncoding: [OFLocale encoding]])) == 0) @throw [OFCreateDirectoryFailedException exceptionWithURL: URL errNo: retrieveError()]; UnLock(lock); #else if (mkdir([path cStringWithEncoding: [OFLocale encoding]], 0777) != 0) @throw [OFCreateDirectoryFailedException exceptionWithURL: URL errNo: errno]; #endif objc_autoreleasePoolPop(pool); } - (OFArray OF_GENERIC(OFURL *) *)contentsOfDirectoryAtURL: (OFURL *)URL { OFMutableArray *URLs = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); OFString *path; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; #if defined(OF_WINDOWS) HANDLE handle; path = [path stringByAppendingString: @"\\*"]; if ([OFSystemInfo isWindowsNT]) { WIN32_FIND_DATAW fd; if ((handle = FindFirstFileW(path.UTF16String, &fd)) == INVALID_HANDLE_VALUE) @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: retrieveError()]; @try { do { OFString *file; if (wcscmp(fd.cFileName, L".") == 0 || wcscmp(fd.cFileName, L"..") == 0) continue; file = [[OFString alloc] initWithUTF16String: fd.cFileName]; @try { [URLs addObject: [URL URLByAppendingPathComponent: file]]; } @finally { [file release]; } } while (FindNextFileW(handle, &fd)); if (GetLastError() != ERROR_NO_MORE_FILES) @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: retrieveError()]; } @finally { FindClose(handle); } } else { OFStringEncoding encoding = [OFLocale encoding]; WIN32_FIND_DATA fd; if ((handle = FindFirstFileA( [path cStringWithEncoding: encoding], &fd)) == INVALID_HANDLE_VALUE) @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: retrieveError()]; @try { do { OFString *file; if (strcmp(fd.cFileName, ".") == 0 || strcmp(fd.cFileName, "..") == 0) continue; file = [[OFString alloc] initWithCString: fd.cFileName encoding: encoding]; @try { [URLs addObject: [URL URLByAppendingPathComponent: file]]; } @finally { [file release]; } } while (FindNextFileA(handle, &fd)); if (GetLastError() != ERROR_NO_MORE_FILES) @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: retrieveError()]; } @finally { FindClose(handle); } } #elif defined(OF_AMIGAOS) OFStringEncoding encoding = [OFLocale encoding]; BPTR lock; if ((lock = Lock([path cStringWithEncoding: encoding], SHARED_LOCK)) == 0) @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: retrieveError()]; @try { # ifdef OF_AMIGAOS4 struct ExamineData *ed; APTR context; if ((context = ObtainDirContextTags(EX_FileLockInput, lock, EX_DoCurrentDir, TRUE, EX_DataFields, EXF_NAME, TAG_END)) == NULL) @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: retrieveError()]; @try { while ((ed = ExamineDir(context)) != NULL) { OFString *file = [[OFString alloc] initWithCString: ed->Name encoding: encoding]; @try { [URLs addObject: [URL URLByAppendingPathComponent: file]]; } @finally { [file release]; } } } @finally { ReleaseDirContext(context); } # else struct FileInfoBlock fib; if (!Examine(lock, &fib)) @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: retrieveError()]; while (ExNext(lock, &fib)) { OFString *file = [[OFString alloc] initWithCString: fib.fib_FileName encoding: encoding]; @try { [URLs addObject: [URL URLByAppendingPathComponent: file]]; } @finally { [file release]; } } # endif if (IoErr() != ERROR_NO_MORE_ENTRIES) @throw [OFReadFailedException exceptionWithObject: self requestedLength: 0 errNo: retrieveError()]; } @finally { UnLock(lock); } #else OFStringEncoding encoding = [OFLocale encoding]; DIR *dir; if ((dir = opendir([path cStringWithEncoding: encoding])) == NULL) @throw [OFOpenItemFailedException exceptionWithURL: URL mode: nil errNo: errno]; # if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) @try { |
︙ | ︙ | |||
1232 1233 1234 1235 1236 1237 1238 | if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) continue; file = [[OFString alloc] initWithCString: dirent->d_name encoding: encoding]; @try { | | > | | > | | | | | | < | 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 | if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) continue; file = [[OFString alloc] initWithCString: dirent->d_name encoding: encoding]; @try { [URLs addObject: [URL URLByAppendingPathComponent: file]]; } @finally { [file release]; } } } @finally { closedir(dir); # if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS) [readdirMutex unlock]; # endif } #endif [URLs makeImmutable]; objc_autoreleasePoolPop(pool); return URLs; } - (void)removeItemAtURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); OFString *path; int error; Stat s; if (URL == nil) @throw [OFInvalidArgumentException exception]; if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; if ((error = lstatWrapper(path, &s)) != 0) @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: error]; if (S_ISDIR(s.st_mode)) { OFArray OF_GENERIC(OFURL *) *contents; @try { contents = [self contentsOfDirectoryAtURL: URL]; } @catch (id e) { /* * Only convert exceptions to * OFRemoveItemFailedException that have an errNo * property. This covers all I/O related exceptions * from the operations used to remove an item, all * others should be left as is. */ if ([e respondsToSelector: @selector(errNo)]) @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: [e errNo]]; @throw e; } for (OFURL *item in contents) { void *pool2 = objc_autoreleasePoolPush(); [self removeItemAtURL: item]; objc_autoreleasePoolPop(pool2); } #ifndef OF_AMIGAOS int status; |
︙ | ︙ | |||
1334 1335 1336 1337 1338 1339 1340 | @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: errno]; #endif } #ifdef OF_AMIGAOS | | < < | > | < | < | | | | | 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 | @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: errno]; #endif } #ifdef OF_AMIGAOS if (!DeleteFile([path cStringWithEncoding: [OFLocale encoding]])) @throw [OFRemoveItemFailedException exceptionWithURL: URL errNo: retrieveError()]; #endif objc_autoreleasePoolPop(pool); } #ifdef OF_FILE_MANAGER_SUPPORTS_LINKS - (void)linkItemAtURL: (OFURL *)source toURL: (OFURL *)destination { void *pool = objc_autoreleasePoolPush(); OFString *sourcePath, *destinationPath; if (source == nil || destination == nil) @throw [OFInvalidArgumentException exception]; if (![source.scheme isEqual: _scheme] || ![destination.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; sourcePath = source.fileSystemRepresentation; destinationPath = destination.fileSystemRepresentation; # ifndef OF_WINDOWS OFStringEncoding encoding = [OFLocale encoding]; if (link([sourcePath cStringWithEncoding: encoding], [destinationPath cStringWithEncoding: encoding]) != 0) @throw [OFLinkFailedException exceptionWithSourceURL: source destinationURL: destination errNo: errno]; # else if (createHardLinkWFuncPtr == NULL) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; if (!createHardLinkWFuncPtr(destinationPath.UTF16String, sourcePath.UTF16String, NULL)) @throw [OFLinkFailedException exceptionWithSourceURL: source destinationURL: destination errNo: retrieveError()]; # endif objc_autoreleasePoolPop(pool); } #endif #ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS |
︙ | ︙ | |||
1404 1405 1406 1407 1408 1409 1410 | if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; # ifndef OF_WINDOWS | | | | > | | < | | < < | < | | 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 | if (![URL.scheme isEqual: _scheme]) @throw [OFInvalidArgumentException exception]; path = URL.fileSystemRepresentation; # ifndef OF_WINDOWS OFStringEncoding encoding = [OFLocale encoding]; if (symlink([target cStringWithEncoding: encoding], [path cStringWithEncoding: encoding]) != 0) @throw [OFCreateSymbolicLinkFailedException exceptionWithURL: URL target: target errNo: errno]; # else if (createSymbolicLinkWFuncPtr == NULL) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; if (!createSymbolicLinkWFuncPtr(path.UTF16String, target.UTF16String, 0)) @throw [OFCreateSymbolicLinkFailedException exceptionWithURL: URL target: target errNo: retrieveError()]; # endif objc_autoreleasePoolPop(pool); } #endif - (bool)moveItemAtURL: (OFURL *)source toURL: (OFURL *)destination { void *pool; if (![source.scheme isEqual: _scheme] || ![destination.scheme isEqual: _scheme]) return false; if ([self fileExistsAtURL: destination]) @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: EEXIST]; pool = objc_autoreleasePoolPush(); #ifdef OF_AMIGAOS OFStringEncoding encoding = [OFLocale encoding]; if (!Rename([source.fileSystemRepresentation cStringWithEncoding: encoding], [destination.fileSystemRepresentation cStringWithEncoding: encoding])) @throw [OFMoveItemFailedException exceptionWithSourceURL: source destinationURL: destination errNo: retrieveError()]; #else int status; # ifdef OF_WINDOWS if ([OFSystemInfo isWindowsNT]) status = _wrename(source.fileSystemRepresentation.UTF16String, destination.fileSystemRepresentation.UTF16String); else { # endif OFStringEncoding encoding = [OFLocale encoding]; status = rename([source.fileSystemRepresentation cStringWithEncoding: encoding], [destination.fileSystemRepresentation cStringWithEncoding: encoding]); # ifdef OF_WINDOWS } |
︙ | ︙ |
Modified src/OFGZIPStream.h from [9a326fe541] to [40a91bbae5].
1 | /* | < < | > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | | | | | | | | | | | | < < < < < < < < < < < < < < < < | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFStream.h" #import "OFDate.h" @class OFInflateStream; OF_ASSUME_NONNULL_BEGIN /** * @brief The operating system on which compressed the data. */ typedef enum { OFGZIPStreamOperatingSystemFAT = 0, OFGZIPStreamOperatingSystemAmiga = 1, OFGZIPStreamOperatingSystemVMS = 2, OFGZIPStreamOperatingSystemUNIX = 3, OFGZIPStreamOperatingSystemVM_CMS = 4, OFGZIPStreamOperatingSystemAtariTOS = 5, OFGZIPStreamOperatingSystemHPFS = 6, OFGZIPStreamOperatingSystemMacintosh = 7, OFGZIPStreamOperatingSystemZSystem = 8, OFGZIPStreamOperatingSystemCPM = 9, OFGZIPStreamOperatingSystemTOPS20 = 10, OFGZIPStreamOperatingSystemNTFS = 11, OFGZIPStreamOperatingSystemQDO = 12, OFGZIPStreamOperatingSystemAcornRISCOS = 13, OFGZIPStreamOperatingSystemUnknown = 255 } OFGZIPStreamOperatingSystem; /** * @class OFGZIPStream OFGZIPStream.h ObjFW/OFGZIPStream.h * * @brief A class that handles GZIP compression and decompression transparently * for an underlying stream. */ OF_SUBCLASSING_RESTRICTED @interface OFGZIPStream: OFStream { OFStream *_stream; OFInflateStream *_Nullable _inflateStream; enum { OFGZIPStreamStateID1, OFGZIPStreamStateID2, OFGZIPStreamStateCompressionMethod, OFGZIPStreamStateFlags, OFGZIPStreamStateModificationDate, OFGZIPStreamStateExtraFlags, OFGZIPStreamStateOperatingSystem, OFGZIPStreamStateExtraLength, OFGZIPStreamStateExtra, OFGZIPStreamStateName, OFGZIPStreamStateComment, OFGZIPStreamStateHeaderCRC16, OFGZIPStreamStateData, OFGZIPStreamStateCRC32, OFGZIPStreamStateUncompressedSize } _state; enum { OFGZIPStreamFlagText = 0x01, OFGZIPStreamFlagHeaderCRC16 = 0x02, OFGZIPStreamFlagExtra = 0x04, OFGZIPStreamFlagName = 0x08, OFGZIPStreamFlagComment = 0x10 } _flags; uint8_t _extraFlags; OFGZIPStreamOperatingSystem _operatingSystemMadeOn; size_t _bytesRead; uint8_t _buffer[4]; OFDate *_Nullable _modificationDate; uint16_t _extraLength; uint32_t _CRC32, _uncompressedSize; } /** * @brief The operating system on which the data was compressed. * * This property is only guaranteed to be available once @ref atEndOfStream is * true. */ @property (readonly, nonatomic) OFGZIPStreamOperatingSystem operatingSystemMadeOn; /** * @brief The modification date of the original file. * * This property is only guaranteed to be available once @ref atEndOfStream is * true. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFDate *modificationDate; /** * @brief Creates a new OFGZIPStream with the specified underlying stream. * * @param stream The underlying stream for the OFGZIPStream * @param mode The mode for the OFGZIPStream. Valid modes are "r" for reading * and "w" for writing. * @return A new, autoreleased OFGZIPStream */ + (instancetype)streamWithStream: (OFStream *)stream mode: (OFString *)mode; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFGZIPStream with the specified * underlying stream. * |
︙ | ︙ |
Modified src/OFGZIPStream.m from [42379805f3] to [947da42ac6].
1 | /* | < < | | < | | < | < | < | < | < | | | | | < | | | | | < | | | < | | < | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFGZIPStream.h" #import "OFCRC32.h" #import "OFDate.h" #import "OFInflateStream.h" #import "OFChecksumMismatchException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFTruncatedDataException.h" @implementation OFGZIPStream @synthesize operatingSystemMadeOn = _operatingSystemMadeOn; @synthesize modificationDate = _modificationDate; + (instancetype)streamWithStream: (OFStream *)stream mode: (OFString *)mode { return [[[self alloc] initWithStream: stream mode: mode] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode { self = [super init]; @try { if (![mode isEqual: @"r"]) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: nil]; _stream = [stream retain]; _operatingSystemMadeOn = OFGZIPStreamOperatingSystemUnknown; _CRC32 = ~0; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_stream != nil) [self close]; [_inflateStream release]; [_modificationDate release]; [super dealloc]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; for (;;) { uint8_t byte; uint32_t CRC32, uncompressedSize; if (_stream.atEndOfStream) { if (_state != OFGZIPStreamStateID1) @throw [OFTruncatedDataException exception]; return 0; } switch (_state) { case OFGZIPStreamStateID1: case OFGZIPStreamStateID2: case OFGZIPStreamStateCompressionMethod: if ([_stream readIntoBuffer: &byte length: 1] < 1) return 0; if ((_state == OFGZIPStreamStateID1 && byte != 0x1F) || (_state == OFGZIPStreamStateID2 && byte != 0x8B) || (_state == OFGZIPStreamStateCompressionMethod && byte != 8)) @throw [OFInvalidFormatException exception]; _state++; break; case OFGZIPStreamStateFlags: if ([_stream readIntoBuffer: &byte length: 1] < 1) return 0; _flags = byte; _state++; break; case OFGZIPStreamStateModificationDate: _bytesRead += [_stream readIntoBuffer: _buffer + _bytesRead length: 4 - _bytesRead]; if (_bytesRead < 4) return 0; [_modificationDate release]; _modificationDate = nil; _modificationDate = [[OFDate alloc] initWithTimeIntervalSince1970: (_buffer[3] << 24) | (_buffer[2] << 16) | (_buffer[1] << 8) | _buffer[0]]; _bytesRead = 0; _state++; break; case OFGZIPStreamStateExtraFlags: if ([_stream readIntoBuffer: &byte length: 1] < 1) return 0; _extraFlags = byte; _state++; break; case OFGZIPStreamStateOperatingSystem: if ([_stream readIntoBuffer: &byte length: 1] < 1) return 0; _operatingSystemMadeOn = byte; _state++; break; case OFGZIPStreamStateExtraLength: if (!(_flags & OFGZIPStreamFlagExtra)) { _state += 2; break; } _bytesRead += [_stream readIntoBuffer: _buffer + _bytesRead length: 2 - _bytesRead]; if (_bytesRead < 2) return 0; _extraLength = (_buffer[1] << 8) | _buffer[0]; _bytesRead = 0; _state++; break; case OFGZIPStreamStateExtra: { char tmp[512]; size_t toRead = _extraLength - _bytesRead; if (toRead > 512) toRead = 512; _bytesRead += [_stream readIntoBuffer: tmp length: toRead]; } if (_bytesRead < _extraLength) return 0; _bytesRead = 0; _state++; break; case OFGZIPStreamStateName: if (!(_flags & OFGZIPStreamFlagName)) { _state++; break; } do { if ([_stream readIntoBuffer: &byte length: 1] < 1) return 0; } while (byte != 0); _state++; break; case OFGZIPStreamStateComment: if (!(_flags & OFGZIPStreamFlagComment)) { _state++; break; } do { if ([_stream readIntoBuffer: &byte length: 1] < 1) return 0; } while (byte != 0); _state++; break; case OFGZIPStreamStateHeaderCRC16: if (!(_flags & OFGZIPStreamFlagHeaderCRC16)) { _state++; break; } _bytesRead += [_stream readIntoBuffer: _buffer + _bytesRead length: 2 - _bytesRead]; if (_bytesRead < 2) return 0; /* * Header CRC16 is not checked, as I could not find a * single file in the wild that actually has a header * CRC16 - and thus no file to test against. */ _bytesRead = 0; _state++; break; case OFGZIPStreamStateData: if (_inflateStream == nil) _inflateStream = [[OFInflateStream alloc] initWithStream: _stream]; if (!_inflateStream.atEndOfStream) { size_t bytesRead = [_inflateStream readIntoBuffer: buffer length: length]; _CRC32 = OFCRC32(_CRC32, buffer, bytesRead); _uncompressedSize += bytesRead; return bytesRead; } [_inflateStream release]; _inflateStream = nil; _state++; break; case OFGZIPStreamStateCRC32: _bytesRead += [_stream readIntoBuffer: _buffer length: 4 - _bytesRead]; if (_bytesRead < 4) return 0; CRC32 = ((uint32_t)_buffer[3] << 24) | |
︙ | ︙ | |||
281 282 283 284 285 286 287 | expectedChecksum: expected]; } _bytesRead = 0; _CRC32 = ~0; _state++; break; | | | | | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | expectedChecksum: expected]; } _bytesRead = 0; _CRC32 = ~0; _state++; break; case OFGZIPStreamStateUncompressedSize: _bytesRead += [_stream readIntoBuffer: _buffer length: 4 - _bytesRead]; uncompressedSize = ((uint32_t)_buffer[3] << 24) | (_buffer[2] << 16) | (_buffer[1] << 8) | _buffer[0]; if (_uncompressedSize != uncompressedSize) { OFString *actual = [OFString stringWithFormat: @"%" PRIu32, _uncompressedSize]; OFString *expected = [OFString stringWithFormat: @"%" PRIu32, uncompressedSize]; @throw [OFChecksumMismatchException exceptionWithActualChecksum: actual expectedChecksum: expected]; } _bytesRead = 0; _uncompressedSize = 0; _state = OFGZIPStreamStateID1; break; } } } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; return _stream.atEndOfStream; } - (bool)hasDataInReadBuffer { if (_state == OFGZIPStreamStateData) return (super.hasDataInReadBuffer || _inflateStream.hasDataInReadBuffer); return (super.hasDataInReadBuffer || _stream.hasDataInReadBuffer); } - (void)close |
︙ | ︙ |
Modified src/OFHMAC.h from [e53629b1a1] to [618167fc85].
1 | /* | < < | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFCryptographicHash.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFHMAC OFHMAC.h ObjFW/OFHMAC.h * * @brief A class which provides methods to calculate an HMAC. */ OF_SUBCLASSING_RESTRICTED @interface OFHMAC: OFObject { Class <OFCryptographicHash> _hashClass; bool _allowsSwappableMemory; id <OFCryptographicHash> _Nullable _outerHash, _innerHash; id <OFCryptographicHash> _Nullable _outerHashCopy, _innerHashCopy; bool _calculated; } /** * @brief The class for the cryptographic hash used by the HMAC. */ @property (readonly, nonatomic) Class <OFCryptographicHash> hashClass; /** * @brief Whether data may be stored in swappable memory. */ @property (readonly, nonatomic) bool allowsSwappableMemory; /** |
︙ | ︙ | |||
62 63 64 65 66 67 68 | /** * @brief Returns a new OFHMAC with the specified hashing algorithm. * * @param hashClass The class of the hashing algorithm * @param allowsSwappableMemory Whether data may be stored in swappable memory * @return A new, autoreleased OFHMAC */ | | | | < | | > > > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | /** * @brief Returns a new OFHMAC with the specified hashing algorithm. * * @param hashClass The class of the hashing algorithm * @param allowsSwappableMemory Whether data may be stored in swappable memory * @return A new, autoreleased OFHMAC */ + (instancetype)HMACWithHashClass: (Class <OFCryptographicHash>)hashClass allowsSwappableMemory: (bool)allowsSwappableMemory; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initialized an already allocated OFHMAC with the specified hashing * algorithm. * * @param hashClass The class of the hashing algorithm * @param allowsSwappableMemory Whether data may be stored in swappable memory * @return An initialized OFHMAC */ - (instancetype)initWithHashClass: (Class <OFCryptographicHash>)hashClass allowsSwappableMemory: (bool)allowsSwappableMemory OF_DESIGNATED_INITIALIZER; /** * @brief Sets the key for the HMAC. * * @note This resets the HMAC! * * @warning This invalidates any pointer previously returned by @ref digest. If * you are still interested in the previous digest, you need to memcpy * it yourself before calling @ref setKey:length:! * * @param key The key for the HMAC * @param length The length of the key for the HMAC */ - (void)setKey: (const void *)key length: (size_t)length; /** * @brief Adds a buffer to the HMAC to be calculated. * * @param buffer The buffer which should be included into the calculation * @param length The length of the buffer */ - (void)updateWithBuffer: (const void *)buffer length: (size_t)length; /** * @brief 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 * @ref setKey:length:. |
︙ | ︙ |
Modified src/OFHMAC.m from [e732705f70] to [2ceebc7fc2].
1 | /* | < < | > | | | < | | < | < > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFHMAC.h" #import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFHashNotCalculatedException.h" #import "OFInvalidArgumentException.h" @implementation OFHMAC @synthesize hashClass = _hashClass; @synthesize allowsSwappableMemory = _allowsSwappableMemory; + (instancetype)HMACWithHashClass: (Class <OFCryptographicHash>)class allowsSwappableMemory: (bool)allowsSwappableMemory { return [[[self alloc] initWithHashClass: class allowsSwappableMemory: allowsSwappableMemory] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithHashClass: (Class <OFCryptographicHash>)class allowsSwappableMemory: (bool)allowsSwappableMemory { self = [super init]; _hashClass = class; _allowsSwappableMemory = allowsSwappableMemory; return self; } - (void)dealloc { [_outerHash release]; [_innerHash release]; [_outerHashCopy release]; [_innerHashCopy release]; [super dealloc]; } - (void)setKey: (const void *)key length: (size_t)length { void *pool = objc_autoreleasePoolPush(); size_t blockSize = [_hashClass blockSize]; OFSecureData *outerKeyPad = [OFSecureData dataWithCount: blockSize allowsSwappableMemory: _allowsSwappableMemory]; OFSecureData *innerKeyPad = [OFSecureData dataWithCount: blockSize allowsSwappableMemory: _allowsSwappableMemory]; unsigned char *outerKeyPadItems = outerKeyPad.mutableItems; unsigned char *innerKeyPadItems = innerKeyPad.mutableItems; [_outerHash release]; [_innerHash release]; [_outerHashCopy release]; [_innerHashCopy release]; _outerHash = _innerHash = _outerHashCopy = _innerHashCopy = nil; @try { if (length > blockSize) { id <OFCryptographicHash> hash = [_hashClass hashWithAllowsSwappableMemory: _allowsSwappableMemory]; [hash updateWithBuffer: key length: length]; [hash calculate]; length = hash.digestSize; if OF_UNLIKELY (length > blockSize) length = blockSize; memcpy(outerKeyPadItems, hash.digest, length); memcpy(innerKeyPadItems, hash.digest, length); } else { memcpy(outerKeyPadItems, key, length); memcpy(innerKeyPadItems, key, length); } memset(outerKeyPadItems + length, 0, blockSize - length); memset(innerKeyPadItems + length, 0, blockSize - length); for (size_t i = 0; i < blockSize; i++) { outerKeyPadItems[i] ^= 0x5C; innerKeyPadItems[i] ^= 0x36; } _outerHash = [[_hashClass hashWithAllowsSwappableMemory: _allowsSwappableMemory] retain]; _innerHash = [[_hashClass hashWithAllowsSwappableMemory: _allowsSwappableMemory] retain]; [_outerHash updateWithBuffer: outerKeyPadItems length: blockSize]; [_innerHash updateWithBuffer: innerKeyPadItems length: blockSize]; } @catch (id e) { |
︙ | ︙ | |||
129 130 131 132 133 134 135 | _outerHashCopy = [_outerHash copy]; _innerHashCopy = [_innerHash copy]; _calculated = false; } | | < | > > > > > > > > > > > > > | > > < < < | < | < < < | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | _outerHashCopy = [_outerHash copy]; _innerHashCopy = [_innerHash copy]; _calculated = false; } - (void)updateWithBuffer: (const void *)buffer length: (size_t)length { if (_innerHash == nil) @throw [OFInvalidArgumentException exception]; if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; [_innerHash updateWithBuffer: buffer length: length]; } - (void)calculate { if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; if (_outerHash == nil || _innerHash == nil) @throw [OFInvalidArgumentException exception]; [_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 { return [_hashClass digestSize]; |
︙ | ︙ |
Modified src/OFHTTPClient.h from [428c441451] to [4532ba7b26].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 | @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFHTTPClient; @class OFHTTPRequest; @class OFHTTPResponse; @class OFStream; @class OFTCPSocket; @class OFURL; /** * @protocol OFHTTPClientDelegate OFHTTPClient.h ObjFW/OFHTTPClient.h * * @brief A delegate for OFHTTPClient. */ | > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFHTTPClient; @class OFHTTPRequest; @class OFHTTPResponse; @class OFStream; @class OFTCPSocket; @class OFTLSStream; @class OFURL; /** * @protocol OFHTTPClientDelegate OFHTTPClient.h ObjFW/OFHTTPClient.h * * @brief A delegate for OFHTTPClient. */ |
︙ | ︙ | |||
48 49 50 51 52 53 54 | - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (nullable OFHTTPResponse *)response exception: (nullable id)exception; @optional /** | | < < | | | | | | | | > > > > > > > > > > > > > > | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (nullable OFHTTPResponse *)response exception: (nullable id)exception; @optional /** * @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. * * @param client The OFHTTPClient that wants to send the body * @param requestBody A stream into which the body of the request should be |
︙ | ︙ | |||
134 135 136 137 138 139 140 | @interface OFHTTPClient: OFObject { #ifdef OF_HTTPCLIENT_M @public #endif OFObject <OFHTTPClientDelegate> *_Nullable _delegate; bool _allowsInsecureRedirects, _inProgress; | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | @interface OFHTTPClient: OFObject { #ifdef OF_HTTPCLIENT_M @public #endif OFObject <OFHTTPClientDelegate> *_Nullable _delegate; bool _allowsInsecureRedirects, _inProgress; OFStream *_Nullable _stream; OFURL *_Nullable _lastURL; bool _lastWasHEAD; OFHTTPResponse *_Nullable _lastResponse; } /** * @brief The delegate of the HTTP request. |
︙ | ︙ |
Modified src/OFHTTPClient.m from [c27ed01d4c] to [74f8b0c30d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" #import "OFKernelEventObserver.h" #import "OFNumber.h" #import "OFRunLoop.h" #import "OFString.h" #import "OFTCPSocket.h" #import "OFURL.h" #import "OFAlreadyConnectedException.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" #import "OFUnsupportedVersionException.h" #import "OFWriteFailedException.h" | > < | < | > | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" #import "OFKernelEventObserver.h" #import "OFNumber.h" #import "OFRunLoop.h" #import "OFString.h" #import "OFTCPSocket.h" #import "OFTLSStream.h" #import "OFURL.h" #import "OFAlreadyConnectedException.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" #import "OFUnsupportedVersionException.h" #import "OFWriteFailedException.h" static const unsigned int defaultRedirects = 10; OF_DIRECT_MEMBERS @interface OFHTTPClientRequestHandler: OFObject <OFTCPSocketDelegate, OFTLSStreamDelegate> { @public OFHTTPClient *_client; OFHTTPRequest *_request; unsigned int _redirects; bool _firstLine; OFString *_version; |
︙ | ︙ | |||
73 74 75 76 77 78 79 | - (void)closeAndReconnect; @end OF_DIRECT_MEMBERS @interface OFHTTPClientRequestBodyStream: OFStream <OFReadyForWritingObserving> { OFHTTPClientRequestHandler *_handler; | | | | | | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | - (void)closeAndReconnect; @end OF_DIRECT_MEMBERS @interface OFHTTPClientRequestBodyStream: OFStream <OFReadyForWritingObserving> { OFHTTPClientRequestHandler *_handler; OFStream *_stream; bool _chunked; unsigned long long _toWrite; bool _atEndOfStream; } - (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler stream: (OFStream *)stream; @end OF_DIRECT_MEMBERS @interface OFHTTPClientResponse: OFHTTPResponse <OFReadyForReadingObserving> { OFStream *_stream; bool _hasContentLength, _chunked, _keepAlive; bool _atEndOfStream, _setAtEndOfStream; long long _toRead; } @property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive; - (instancetype)initWithStream: (OFStream *)stream; @end OF_DIRECT_MEMBERS @interface OFHTTPClientSyncPerformer: OFObject <OFHTTPClientDelegate> { OFHTTPClient *_client; OFObject <OFHTTPClientDelegate> *_delegate; OFHTTPResponse *_response; } - (instancetype)initWithClient: (OFHTTPClient *)client; - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects; @end static OFString * constructRequestString(OFHTTPRequest *request) { void *pool = objc_autoreleasePoolPush(); OFHTTPRequestMethod method = request.method; OFURL *URL = request.URL; OFString *path; OFString *user = URL.user, *password = URL.password; OFMutableString *requestString; OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; bool hasContentLength, chunked; OFEnumerator OF_GENERIC(OFString *) *keyEnumerator, *objectEnumerator; OFString *key, *object; if (URL.path != nil) path = URL.URLEncodedPath; else path = @"/"; requestString = [OFMutableString stringWithFormat: @"%s %@", OFHTTPRequestMethodName(method), path]; if (URL.query != nil) { [requestString appendString: @"?"]; [requestString appendString: URL.URLEncodedQuery]; } [requestString appendString: @" HTTP/"]; |
︙ | ︙ | |||
152 153 154 155 156 157 158 | if ([headers objectForKey: @"Host"] == nil) { OFNumber *port = URL.port; if (port != nil) { OFString *host = [OFString stringWithFormat: @"%@:%@", URL.URLEncodedHost, port]; | | < < | | < | < | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | if ([headers objectForKey: @"Host"] == nil) { OFNumber *port = URL.port; if (port != nil) { OFString *host = [OFString stringWithFormat: @"%@:%@", URL.URLEncodedHost, port]; [headers setObject: host forKey: @"Host"]; } else [headers setObject: URL.URLEncodedHost forKey: @"Host"]; } if ((user.length > 0 || password.length > 0) && [headers objectForKey: @"Authorization"] == nil) { OFMutableData *authorizationData = [OFMutableData data]; OFString *authorization; [authorizationData addItems: user.UTF8String count: user.UTF8StringLength]; [authorizationData addItem: ":"]; [authorizationData addItems: password.UTF8String count: password.UTF8StringLength]; authorization = [OFString stringWithFormat: @"Basic %@", authorizationData.stringByBase64Encoding]; [headers setObject: authorization forKey: @"Authorization"]; } if ([headers objectForKey: @"User-Agent"] == nil) [headers setObject: @"Something using ObjFW " @"<https://objfw.nil.im/>" forKey: @"User-Agent"]; if (request.protocolVersion.major == 1 && request.protocolVersion.minor == 0 && [headers objectForKey: @"Connection"] == nil) [headers setObject: @"keep-alive" forKey: @"Connection"]; hasContentLength = ([headers objectForKey: @"Content-Length"] != nil); chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; if ((hasContentLength || chunked) && [headers objectForKey: @"Content-Type"] == nil) |
︙ | ︙ | |||
221 222 223 224 225 226 227 | static OF_INLINE void normalizeKey(char *str_) { unsigned char *str = (unsigned char *)str_; bool firstLetter = true; while (*str != '\0') { | | < | | | | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | static OF_INLINE void normalizeKey(char *str_) { unsigned char *str = (unsigned char *)str_; bool firstLetter = true; while (*str != '\0') { if (!OFASCIIIsAlpha(*str)) { firstLetter = true; str++; continue; } *str = (firstLetter ? OFASCIIToUpper(*str) : OFASCIIToLower(*str)); firstLetter = false; str++; } } static bool defaultShouldFollow(OFHTTPRequestMethod method, short statusCode) { bool follow; /* * 301, 302 and 307 should only redirect with user confirmation if the * request method is not GET or HEAD. Asking the delegate and getting * true returned is considered user confirmation. */ if (method == OFHTTPRequestMethodGet || method == OFHTTPRequestMethodHead) follow = true; /* 303 should always be redirected and converted to a GET request. */ else if (statusCode == 303) follow = true; else follow = false; |
︙ | ︙ | |||
299 300 301 302 303 304 305 | [_client->_delegate client: _client didPerformRequest: _request response: nil exception: exception]; } | | | | | | | | | | | 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | [_client->_delegate client: _client didPerformRequest: _request response: nil exception: exception]; } - (void)createResponseWithStreamOrThrow: (OFStream *)stream { OFURL *URL = _request.URL; OFHTTPClientResponse *response; OFString *connectionHeader; bool keepAlive; OFString *location; id exception; response = [[[OFHTTPClientResponse alloc] initWithStream: stream] autorelease]; response.protocolVersionString = _version; response.statusCode = _status; response.headers = _serverHeaders; connectionHeader = [_serverHeaders objectForKey: @"Connection"]; if ([_version isEqual: @"1.1"]) { if (connectionHeader != nil) keepAlive = [connectionHeader isEqual: @"close"]; else keepAlive = true; } else { if (connectionHeader != nil) keepAlive = ([connectionHeader caseInsensitiveCompare: @"keep-alive"] == OFOrderedSame); else keepAlive = false; } if (keepAlive) { response.of_keepAlive = true; _client->_stream = [stream retain]; _client->_lastURL = [URL copy]; _client->_lastWasHEAD = (_request.method == OFHTTPRequestMethodHead); _client->_lastResponse = [response retain]; } if (_redirects > 0 && (_status == 301 || _status == 302 || _status == 303 || _status == 307) && (location = [_serverHeaders objectForKey: @"Location"]) != nil) { bool follow = true; OFURL *newURL; OFString *newURLScheme; newURL = [OFURL URLWithString: location relativeToURL: URL]; newURLScheme = newURL.scheme; if ([newURLScheme caseInsensitiveCompare: @"http"] != OFOrderedSame && [newURLScheme caseInsensitiveCompare: @"https"] != OFOrderedSame) follow = false; if (!_client->_allowsInsecureRedirects && [URL.scheme caseInsensitiveCompare: @"https"] == OFOrderedSame && [newURLScheme caseInsensitiveCompare: @"http"] == OFOrderedSame) follow = false; if (follow && [_client->_delegate respondsToSelector: @selector( client:shouldFollowRedirect:statusCode:request:response:)]) follow = [_client->_delegate client: _client shouldFollowRedirect: newURL statusCode: _status |
︙ | ︙ | |||
403 404 405 406 407 408 409 | (object = [objectEnumerator nextObject]) != nil) if ([key hasPrefix: @"Content-"] || [key hasPrefix: @"Transfer-"]) [newHeaders removeObjectForKey: key]; | | | 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | (object = [objectEnumerator nextObject]) != nil) if ([key hasPrefix: @"Content-"] || [key hasPrefix: @"Transfer-"]) [newHeaders removeObjectForKey: key]; newRequest.method = OFHTTPRequestMethodGet; } newRequest.URL = newURL; newRequest.headers = newHeaders; _client->_inProgress = false; |
︙ | ︙ | |||
435 436 437 438 439 440 441 | withObject: _client withObject: _request withObject: response withObject: exception afterDelay: 0]; } | | | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | withObject: _client withObject: _request withObject: response withObject: exception afterDelay: 0]; } - (void)createResponseWithStream: (OFStream *)stream { @try { [self createResponseWithStreamOrThrow: stream]; } @catch (id e) { [self raiseException: e]; } } - (bool)handleFirstLine: (OFString *)line { |
︙ | ︙ | |||
462 463 464 465 466 467 468 | return false; } if (![line hasPrefix: @"HTTP/"] || line.length < 9 || [line characterAtIndex: 8] != ' ') @throw [OFInvalidServerReplyException exception]; | | | | < | | | | | | < | | < | | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 | return false; } if (![line hasPrefix: @"HTTP/"] || line.length < 9 || [line characterAtIndex: 8] != ' ') @throw [OFInvalidServerReplyException exception]; _version = [[line substringWithRange: OFRangeMake(5, 3)] copy]; if (![_version isEqual: @"1.0"] && ![_version isEqual: @"1.1"]) @throw [OFUnsupportedVersionException exceptionWithVersion: _version]; status = [line substringWithRange: OFRangeMake(9, 3)].longLongValue; if (status < 0 || status > 599) @throw [OFInvalidServerReplyException exception]; _status = (short)status; return true; } - (bool)handleServerHeader: (OFString *)line stream: (OFStream *)stream { OFString *key, *value, *old; const char *lineC, *tmp; char *keyC; if (line == nil) @throw [OFInvalidServerReplyException exception]; if (line.length == 0) { [_serverHeaders makeImmutable]; if ([_client->_delegate respondsToSelector: @selector(client: didReceiveHeaders:statusCode:request:)]) [_client->_delegate client: _client didReceiveHeaders: _serverHeaders statusCode: _status request: _request]; stream.delegate = nil; [self performSelector: @selector(createResponseWithStream:) withObject: stream afterDelay: 0]; return false; } lineC = line.UTF8String; if ((tmp = strchr(lineC, ':')) == NULL) @throw [OFInvalidServerReplyException exception]; keyC = OFAllocMemory(tmp - lineC + 1, 1); memcpy(keyC, lineC, tmp - lineC); keyC[tmp - lineC] = '\0'; normalizeKey(keyC); @try { key = [OFString stringWithUTF8StringNoCopy: keyC freeWhenDone: true]; } @catch (id e) { OFFreeMemory(keyC); @throw e; } do { tmp++; } while (*tmp == ' '); value = [OFString stringWithUTF8String: tmp]; old = [_serverHeaders objectForKey: key]; if (old != nil) value = [old stringByAppendingFormat: @",%@", value]; [_serverHeaders setObject: value forKey: key]; return true; } - (bool)stream: (OFStream *)stream didReadLine: (OFString *)line exception: (id)exception { bool ret; if (exception != nil) { if ([exception isKindOfClass: [OFInvalidEncodingException class]]) exception = [OFInvalidServerReplyException exception]; [self raiseException: exception]; return false; } @try { if (_firstLine) { _firstLine = false; ret = [self handleFirstLine: line]; } else ret = [self handleServerHeader: line stream: stream]; } @catch (id e) { [self raiseException: e]; ret = false; } return ret; } - (OFString *)stream: (OFStream *)stream didWriteString: (OFString *)string encoding: (OFStringEncoding)encoding bytesWritten: (size_t)bytesWritten exception: (id)exception { OFDictionary OF_GENERIC(OFString *, OFString *) *headers; bool chunked; if (exception != nil) { |
︙ | ︙ | |||
602 603 604 605 606 607 608 | chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; if (chunked || [headers objectForKey: @"Content-Length"] != nil) { stream.delegate = nil; OFStream *requestBody = [[[OFHTTPClientRequestBodyStream alloc] | | < | | | > > > > | > > > > > > | > > > > > > | > > | | | | | | | > > > > | | > > > > > > > > > > > > > > > | | | | | | | | | > > < < < < | < | < < | < | | | 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 | chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; if (chunked || [headers objectForKey: @"Content-Length"] != nil) { stream.delegate = nil; OFStream *requestBody = [[[OFHTTPClientRequestBodyStream alloc] initWithHandler: self stream: stream] autorelease]; if ([_client->_delegate respondsToSelector: @selector(client:wantsRequestBody:request:)]) [_client->_delegate client: _client wantsRequestBody: requestBody request: _request]; } else [stream asyncReadLine]; return nil; } - (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 streams's write buffer in case we need to resend * the entire request (e.g. in case a keep-alive connection timed out). */ @try { [stream asyncWriteString: constructRequestString(_request)]; } @catch (id e) { [self raiseException: e]; return; } } - (void)socket: (OFTCPSocket *)sock didConnectToHost: (OFString *)host port: (uint16_t)port exception: (id)exception { 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; } [self performSelector: @selector(handleStream:) withObject: stream afterDelay: 0]; } - (void)start { OFURL *URL = _request.URL; OFStream *stream; /* Can we reuse the last socket? */ 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 _stream to nil, so that in case of an error it won't be * reused. If everything is successful, we set _stream again * at the end. */ stream = [_client->_stream autorelease]; _client->_stream = nil; [_client->_lastURL release]; _client->_lastURL = nil; [_client->_lastResponse release]; _client->_lastResponse = nil; stream.delegate = self; [self performSelector: @selector(handleStream:) withObject: stream afterDelay: 0]; } else [self closeAndReconnect]; } - (void)closeAndReconnect { @try { OFURL *URL = _request.URL; OFTCPSocket *sock; uint16_t port; OFNumber *URLPort; [_client close]; sock = [OFTCPSocket socket]; if ([URL.scheme caseInsensitiveCompare: @"https"] == OFOrderedSame) port = 443; else port = 80; URLPort = URL.port; if (URLPort != nil) port = URLPort.unsignedShortValue; sock.delegate = self; [sock asyncConnectToHost: URL.host port: port]; } @catch (id e) { [self raiseException: e]; } } @end @implementation OFHTTPClientRequestBodyStream - (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler stream: (OFStream *)stream { self = [super init]; @try { OFDictionary OF_GENERIC(OFString *, OFString *) *headers; OFString *transferEncoding, *contentLengthString; _handler = [handler retain]; _stream = [stream retain]; headers = _handler->_request.headers; transferEncoding = [headers objectForKey: @"Transfer-Encoding"]; _chunked = [transferEncoding isEqual: @"chunked"]; contentLengthString = [headers objectForKey: @"Content-Length"]; |
︙ | ︙ | |||
766 767 768 769 770 771 772 | } return self; } - (void)dealloc { | | | < < < > | | < | | | | < > < | | < < < | < < < < < < < | | | | | | | > | | | | | 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 | } return self; } - (void)dealloc { if (_stream != nil) [self close]; [_handler release]; [super dealloc]; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { /* TODO: Use non-blocking writes */ 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 * the end of stream. */ if (length == 0) return 0; if (_atEndOfStream) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: ENOTCONN]; if (_chunked) [_stream writeFormat: @"%zX\r\n", length]; else if (length > _toWrite) @throw [OFOutOfRangeException exception]; [_stream writeBuffer: buffer length: length]; if (_chunked) [_stream writeString: @"\r\n"]; if (!_chunked) { _toWrite -= length; if (_toWrite == 0) _atEndOfStream = true; } return length; } - (bool)lowlevelIsAtEndOfStream { return _atEndOfStream; } - (void)close { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_chunked) [_stream writeString: @"0\r\n\r\n"]; else if (_toWrite > 0) @throw [OFTruncatedDataException exception]; _stream.delegate = _handler; [_stream asyncReadLine]; [_stream release]; _stream = nil; [super close]; } - (int)fileDescriptorForWriting { return ((OFStream <OFReadyForWritingObserving> *)_stream) .fileDescriptorForWriting; } @end @implementation OFHTTPClientResponse @synthesize of_keepAlive = _keepAlive; - (instancetype)initWithStream: (OFStream *)stream { self = [super init]; _stream = [stream retain]; return self; } - (void)dealloc { if (_stream != nil) [self close]; [super dealloc]; } - (void)setHeaders: (OFDictionary *)headers { |
︙ | ︙ | |||
908 909 910 911 912 913 914 | _toRead = (long long)toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; } } } | | < | < | | < | < < | < | < | < | | | | | 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 | _toRead = (long long)toRead; } @catch (OFInvalidFormatException *e) { @throw [OFInvalidServerReplyException exception]; } } } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) return 0; if (!_hasContentLength && !_chunked) return [_stream readIntoBuffer: buffer length: length]; if (_stream.atEndOfStream) @throw [OFTruncatedDataException exception]; /* Content-Length */ if (!_chunked) { size_t ret; if (length > (unsigned long long)_toRead) length = (size_t)_toRead; ret = [_stream readIntoBuffer: buffer length: length]; if (ret > length) @throw [OFOutOfRangeException exception]; _toRead -= ret; if (_toRead == 0) _atEndOfStream = true; return ret; } /* Chunked */ if (_toRead == -2) { char tmp[2]; switch ([_stream readIntoBuffer: tmp length: 2]) { case 2: _toRead++; if (tmp[1] != '\n') @throw [OFInvalidServerReplyException exception]; case 1: _toRead++; if (tmp[0] != '\r') @throw [OFInvalidServerReplyException exception]; } if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead == -1) { char tmp; if ([_stream readIntoBuffer: &tmp length: 1] == 1) { _toRead++; if (tmp != '\n') @throw [OFInvalidServerReplyException exception]; } if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead > 0) { if (length > (unsigned long long)_toRead) length = (size_t)_toRead; length = [_stream readIntoBuffer: buffer length: length]; _toRead -= length; if (_toRead == 0) _toRead = -2; return length; } else { void *pool = objc_autoreleasePoolPush(); OFString *line; size_t pos; @try { line = [_stream tryReadLine]; } @catch (OFInvalidEncodingException *e) { @throw [OFInvalidServerReplyException exception]; } if (line == nil) return 0; pos = [line rangeOfString: @";"].location; if (pos != OFNotFound) line = [line substringToIndex: pos]; if (line.length < 1) { /* * We have read the empty string because the stream is * at end of stream. */ if (_stream.atEndOfStream && pos == OFNotFound) @throw [OFTruncatedDataException exception]; else @throw [OFInvalidServerReplyException exception]; } @try { |
︙ | ︙ | |||
1053 1054 1055 1056 1057 1058 1059 | } - (bool)lowlevelIsAtEndOfStream { if (_atEndOfStream) return true; | | | | > | | | | | | 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 | } - (bool)lowlevelIsAtEndOfStream { if (_atEndOfStream) return true; if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (!_hasContentLength && !_chunked) return _stream.atEndOfStream; return _atEndOfStream; } - (int)fileDescriptorForReading { if (_stream == nil) return -1; return ((OFStream <OFReadyForReadingObserving> *)_stream) .fileDescriptorForReading; } - (bool)hasDataInReadBuffer { return (super.hasDataInReadBuffer || _stream.hasDataInReadBuffer); } - (void)close { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; _atEndOfStream = false; [_stream release]; _stream = nil; [super close]; } @end @implementation OFHTTPClientSyncPerformer - (instancetype)initWithClient: (OFHTTPClient *)client |
︙ | ︙ | |||
1118 1119 1120 1121 1122 1123 1124 | [super dealloc]; } - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { | | < < < | 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 | [super dealloc]; } - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { [_client asyncPerformRequest: request redirects: redirects]; [[OFRunLoop currentRunLoop] run]; return _response; } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response exception: (id)exception |
︙ | ︙ | |||
1153 1154 1155 1156 1157 1158 1159 | [_delegate client: client didPerformRequest: request response: response exception: nil]; } | | | | | | | | > > > > > > > > > > > | 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 | [_delegate client: client didPerformRequest: request response: response exception: nil]; } - (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:didCreateTLSStream:request:)]) [_delegate client: client didCreateTLSStream: TLSStream request: request]; } - (void)client: (OFHTTPClient *)client wantsRequestBody: (OFStream *)body request: (OFHTTPRequest *)request { if ([_delegate respondsToSelector: |
︙ | ︙ | |||
1224 1225 1226 1227 1228 1229 1230 | [self close]; [super dealloc]; } - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request { | | < | 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 | [self close]; [super dealloc]; } - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request { return [self performRequest: request redirects: defaultRedirects]; } - (OFHTTPResponse *)performRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { void *pool = objc_autoreleasePoolPush(); OFHTTPClientSyncPerformer *syncPerformer = |
︙ | ︙ | |||
1247 1248 1249 1250 1251 1252 1253 | objc_autoreleasePoolPop(pool); return [response autorelease]; } - (void)asyncPerformRequest: (OFHTTPRequest *)request { | | < | | | | | 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 | objc_autoreleasePoolPop(pool); return [response autorelease]; } - (void)asyncPerformRequest: (OFHTTPRequest *)request { [self asyncPerformRequest: request redirects: defaultRedirects]; } - (void)asyncPerformRequest: (OFHTTPRequest *)request redirects: (unsigned int)redirects { void *pool = objc_autoreleasePoolPush(); OFURL *URL = request.URL; OFString *scheme = URL.scheme; if ([scheme caseInsensitiveCompare: @"http"] != OFOrderedSame && [scheme caseInsensitiveCompare: @"https"] != OFOrderedSame) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; if (_inProgress) /* TODO: Find a better exception */ @throw [OFAlreadyConnectedException exception]; _inProgress = true; [[[[OFHTTPClientRequestHandler alloc] initWithClient: self request: request redirects: redirects] autorelease] start]; objc_autoreleasePoolPop(pool); } - (void)close { [_stream release]; _stream = nil; [_lastURL release]; _lastURL = nil; [_lastResponse release]; _lastResponse = nil; } @end |
Modified src/OFHTTPCookie.h from [49a9c4f266] to [c915720e1d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFHTTPCookie.m from [a6b5d4bf43] to [30659cca3c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
66 67 68 69 70 71 72 | (OFDictionary OF_GENERIC(OFString *, OFString *) *)headerFields forURL: (OFURL *)URL { OFMutableArray OF_GENERIC(OFHTTPCookie *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); OFString *string = [headerFields objectForKey: @"Set-Cookie"]; OFString *domain = URL.host; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | (OFDictionary OF_GENERIC(OFString *, OFString *) *)headerFields forURL: (OFURL *)URL { OFMutableArray OF_GENERIC(OFHTTPCookie *) *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); OFString *string = [headerFields objectForKey: @"Set-Cookie"]; OFString *domain = URL.host; const OFUnichar *characters = string.characters; size_t length = string.length, last = 0; enum { statePreName, stateName, stateExpectValue, stateValue, stateQuotedValue, statePostQuotedValue, statePreAttrName, stateAttrName, stateAttrValue } state = statePreName; OFString *name = nil, *value = nil; for (size_t i = 0; i < length; i++) { switch (state) { case statePreName: if (characters[i] != ' ') { state = stateName; last = i; i--; } break; case stateName: if (characters[i] == '=') { name = [string substringWithRange: OFRangeMake(last, i - last)]; state = stateExpectValue; } break; case stateExpectValue: if (characters[i] == '"') { state = stateQuotedValue; last = i + 1; } else { state = stateValue; last = i; } i--; break; case stateValue: if (characters[i] == ';' || characters[i] == ',') { value = [string substringWithRange: OFRangeMake(last, i - last)]; [ret addObject: [OFHTTPCookie cookieWithName: name value: value domain: domain]]; state = (characters[i] == ';' ? statePreAttrName : statePreName); } break; case stateQuotedValue: if (characters[i] == '"') { value = [string substringWithRange: OFRangeMake(last, i - last)]; [ret addObject: [OFHTTPCookie cookieWithName: name value: value domain: domain]]; state = statePostQuotedValue; } break; case statePostQuotedValue: if (characters[i] == ';') state = statePreAttrName; else if (characters[i] == ',') state = statePreName; else @throw [OFInvalidFormatException exception]; break; case statePreAttrName: if (characters[i] != ' ') { state = stateAttrName; last = i; i--; } break; case stateAttrName: if (characters[i] == '=') { name = [string substringWithRange: OFRangeMake(last, i - last)]; state = stateAttrValue; last = i + 1; } else if (characters[i] == ';' || characters[i] == ',') { name = [string substringWithRange: OFRangeMake(last, i - last)]; handleAttribute(ret.lastObject, name, nil); state = (characters[i] == ';' ? statePreAttrName : statePreName); } break; case stateAttrValue: if (characters[i] == ';' || characters[i] == ',') { value = [string substringWithRange: OFRangeMake(last, i - last)]; /* * Expires often contains a comma, even though * the comma is used as a separator for * concatenating headers as per RFC 2616, * meaning RFC 6265 contradicts RFC 2616. * Solve this by special casing this. */ if (characters[i] == ',' && [name caseInsensitiveCompare: @"expires"] == OFOrderedSame && value.length == 3 && ([value isEqual: @"Mon"] || [value isEqual: @"Tue"] || [value isEqual: @"Wed"] || [value isEqual: @"Thu"] || [value isEqual: @"Fri"] || [value isEqual: @"Sat"] || [value isEqual: @"Sun"])) break; handleAttribute(ret.lastObject, name, value); state = (characters[i] == ';' ? statePreAttrName : statePreName); } break; } } switch (state) { case statePreName: case statePostQuotedValue: case statePreAttrName: break; case stateName: case stateQuotedValue: @throw [OFInvalidFormatException exception]; break; case stateValue: value = [string substringWithRange: OFRangeMake(last, length - last)]; [ret addObject: [OFHTTPCookie cookieWithName: name value: value domain: domain]]; break; /* We end up here if the cookie is just foo= */ case stateExpectValue: [ret addObject: [OFHTTPCookie cookieWithName: name value: @"" domain: domain]]; break; case stateAttrName: if (last != length) { name = [string substringWithRange: OFRangeMake(last, length - last)]; handleAttribute(ret.lastObject, name, nil); } break; case stateAttrValue: value = [string substringWithRange: OFRangeMake(last, length - last)]; handleAttribute(ret.lastObject, name, value); break; } objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
361 362 363 364 365 366 367 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | | | 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddHash(&hash, _value.hash); OFHashAddHash(&hash, _domain.hash); OFHashAddHash(&hash, _path.hash); OFHashAddHash(&hash, _expires.hash); OFHashAdd(&hash, _secure); OFHashAdd(&hash, _HTTPOnly); OFHashAddHash(&hash, _extensions.hash); OFHashFinalize(&hash); return hash; } - (id)copy { OFHTTPCookie *copy = [[OFHTTPCookie alloc] initWithName: _name |
︙ | ︙ |
Modified src/OFHTTPCookieManager.h from [bd806f13f2] to [776c67cc36].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
52 53 54 55 56 57 58 | * * @warning This modifies the cookie (e.g. it sets the domain if it is unset)! * If you do not want this, pass a copy! * * @param cookie The cookie to add to the manager * @param URL The URL for which the cookie should be added */ | | < | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | * * @warning This modifies the cookie (e.g. it sets the domain if it is unset)! * If you do not want this, pass a copy! * * @param cookie The cookie to add to the manager * @param URL The URL for which the cookie should be added */ - (void)addCookie: (OFHTTPCookie *)cookie forURL: (OFURL *)URL; /** * @brief Adds the specified cookies for the specified URL. * * @warning This modifies the cookies (e.g. it sets the domain if it is unset)! * If you do not want this, pass copies! * |
︙ | ︙ |
Modified src/OFHTTPCookieManager.m from [f3b5caf32a] to [ab6e7fb16a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
51 52 53 54 55 56 57 | } - (OFArray OF_GENERIC(OFHTTPCookie *) *)cookies { return [[_cookies copy] autorelease]; } | | < | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | } - (OFArray OF_GENERIC(OFHTTPCookie *) *)cookies { return [[_cookies copy] autorelease]; } - (void)addCookie: (OFHTTPCookie *)cookie forURL: (OFURL *)URL { void *pool = objc_autoreleasePoolPush(); OFString *cookieDomain, *URLHost; size_t i; if (![cookie.path hasPrefix: @"/"]) cookie.path = @"/"; if (cookie.secure && [URL.scheme caseInsensitiveCompare: @"https"] != OFOrderedSame) { objc_autoreleasePoolPop(pool); return; } cookieDomain = cookie.domain.lowercaseString; cookie.domain = cookieDomain; |
︙ | ︙ | |||
85 86 87 88 89 90 91 | } i = 0; for (OFHTTPCookie *iter in _cookies) { if ([iter.name isEqual: cookie.name] && [iter.domain isEqual: cookie.domain] && [iter.path isEqual: cookie.path]) { | | < < | < | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | } i = 0; for (OFHTTPCookie *iter in _cookies) { if ([iter.name isEqual: cookie.name] && [iter.domain isEqual: cookie.domain] && [iter.path isEqual: cookie.path]) { [_cookies replaceObjectAtIndex: i withObject: cookie]; objc_autoreleasePoolPop(pool); return; } i++; } [_cookies addObject: cookie]; objc_autoreleasePoolPop(pool); } - (void)addCookies: (OFArray OF_GENERIC(OFHTTPCookie *) *)cookies forURL: (OFURL *)URL { for (OFHTTPCookie *cookie in cookies) [self addCookie: cookie forURL: URL]; } - (OFArray OF_GENERIC(OFHTTPCookie *) *)cookiesForURL: (OFURL *)URL { OFMutableArray *ret = [OFMutableArray array]; for (OFHTTPCookie *cookie in _cookies) { void *pool; OFDate *expires; OFString *cookieDomain, *URLHost, *cookiePath, *URLPath; bool match; expires = cookie.expires; if (expires != nil && expires.timeIntervalSinceNow <= 0) continue; if (cookie.secure && [URL.scheme caseInsensitiveCompare: @"https"] != OFOrderedSame) continue; pool = objc_autoreleasePoolPush(); cookieDomain = cookie.domain.lowercaseString; URLHost = URL.host.lowercaseString; if ([cookieDomain hasPrefix: @"."]) { |
︙ | ︙ |
Modified src/OFHTTPRequest.h from [8374acae4d] to [cc3f0d316f].
1 | /* | < < | | < | | | | | | | | | | < | | < < | | | | | | | < < < < < < < < > > | | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFSocket.h" #import "OFString.h" OF_ASSUME_NONNULL_BEGIN @class OFURL; @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFData; @class OFString; /** @file */ /** * @brief The type of an HTTP request. */ typedef enum { /** OPTIONS */ OFHTTPRequestMethodOptions, /** GET */ OFHTTPRequestMethodGet, /** HEAD */ OFHTTPRequestMethodHead, /** POST */ OFHTTPRequestMethodPost, /** PUT */ OFHTTPRequestMethodPut, /** DELETE */ OFHTTPRequestMethodDelete, /** TRACE */ OFHTTPRequestMethodTrace, /** CONNECT */ OFHTTPRequestMethodConnect } OFHTTPRequestMethod; /** * @struct OFHTTPRequestProtocolVersion OFHTTPRequest.h ObjFW/OFHTTPRequest.h * * @brief The HTTP version of the HTTP request. */ typedef struct OF_BOXABLE { /** The major of the HTTP version */ unsigned char major; /** The minor of the HTTP version */ unsigned char minor; } OFHTTPRequestProtocolVersion; /** * @class OFHTTPRequest OFHTTPRequest.h ObjFW/OFHTTPRequest.h * * @brief A class for storing HTTP requests. */ @interface OFHTTPRequest: OFObject <OFCopying> { OFURL *_URL; OFHTTPRequestMethod _method; OFHTTPRequestProtocolVersion _protocolVersion; OFDictionary OF_GENERIC(OFString *, OFString *) *_Nullable _headers; OFSocketAddress _remoteAddress; bool _hasRemoteAddress; OF_RESERVE_IVARS(OFHTTPRequest, 4) } /** * @brief The URL of the HTTP request. */ @property (copy, nonatomic) OFURL *URL; /** * @brief The protocol version of the HTTP request. */ @property (nonatomic) OFHTTPRequestProtocolVersion protocolVersion; /** * @brief The protocol version of the HTTP request as a string. */ @property (copy, nonatomic) OFString *protocolVersionString; /** * @brief The request method of the HTTP request. */ @property (nonatomic) OFHTTPRequestMethod method; /** * @brief The headers for the HTTP request. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFDictionary OF_GENERIC(OFString *, OFString *) *headers; /** * @brief The remote address from which the request originates. * * @note The setter creates a copy of the remote address. */ @property OF_NULLABLE_PROPERTY (nonatomic) const OFSocketAddress *remoteAddress; /** * @brief Creates a new OFHTTPRequest with the specified URL. * * @param URL The URL for the request * @return A new, autoreleased OFHTTPRequest */ + (instancetype)requestWithURL: (OFURL *)URL; /** * @brief Initializes an already allocated OFHTTPRequest with the specified URL. * * @param URL The URL for the request * @return An initialized OFHTTPRequest */ - (instancetype)initWithURL: (OFURL *)URL; - (instancetype)init OF_UNAVAILABLE; @end #ifdef __cplusplus extern "C" { #endif /** * @brief Returns a C string describing the specified request method. * * @param method The request method which should be described as a C string * @return A C string describing the specified request method */ extern const char *_Nullable OFHTTPRequestMethodName( OFHTTPRequestMethod method); /** * @brief Returns the request method for the specified string. * * @param string The string for which the request method should be returned * @return The request method for the specified string */ extern OFHTTPRequestMethod OFHTTPRequestMethodParseName(OFString *string); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFHTTPRequest.m from [517654630c] to [723c374a89].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFUnsupportedVersionException.h" const char * | | | | | | | | | | | | | | | | | | | | < < < < < | > > | | | < < < < < < < < < < > > > > > | | | < | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFUnsupportedVersionException.h" const char * OFHTTPRequestMethodName(OFHTTPRequestMethod method) { switch (method) { case OFHTTPRequestMethodOptions: return "OPTIONS"; case OFHTTPRequestMethodGet: return "GET"; case OFHTTPRequestMethodHead: return "HEAD"; case OFHTTPRequestMethodPost: return "POST"; case OFHTTPRequestMethodPut: return "PUT"; case OFHTTPRequestMethodDelete: return "DELETE"; case OFHTTPRequestMethodTrace: return "TRACE"; case OFHTTPRequestMethodConnect: return "CONNECT"; } return NULL; } OFHTTPRequestMethod OFHTTPRequestMethodParseName(OFString *string) { if ([string isEqual: @"OPTIONS"]) return OFHTTPRequestMethodOptions; if ([string isEqual: @"GET"]) return OFHTTPRequestMethodGet; if ([string isEqual: @"HEAD"]) return OFHTTPRequestMethodHead; if ([string isEqual: @"POST"]) return OFHTTPRequestMethodPost; if ([string isEqual: @"PUT"]) return OFHTTPRequestMethodPut; if ([string isEqual: @"DELETE"]) return OFHTTPRequestMethodDelete; if ([string isEqual: @"TRACE"]) return OFHTTPRequestMethodTrace; if ([string isEqual: @"CONNECT"]) return OFHTTPRequestMethodConnect; @throw [OFInvalidArgumentException exception]; } @implementation OFHTTPRequest @synthesize URL = _URL, method = _method, headers = _headers; + (instancetype)requestWithURL: (OFURL *)URL { return [[[self alloc] initWithURL: URL] autorelease]; } - (instancetype)initWithURL: (OFURL *)URL { self = [super 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]; [super dealloc]; } - (void)setRemoteAddress: (const OFSocketAddress *)remoteAddress { _hasRemoteAddress = (remoteAddress != NULL); if (_hasRemoteAddress) _remoteAddress = *remoteAddress; } - (const OFSocketAddress *)remoteAddress { if (_hasRemoteAddress) return &_remoteAddress; return NULL; } - (id)copy { OFHTTPRequest *copy = [[OFHTTPRequest alloc] initWithURL: _URL]; @try { copy->_method = _method; copy->_protocolVersion = _protocolVersion; copy.headers = _headers; copy.remoteAddress = self.remoteAddress; } @catch (id e) { [copy release]; @throw e; } |
︙ | ︙ | |||
175 176 177 178 179 180 181 | request->_protocolVersion.major != _protocolVersion.major || request->_protocolVersion.minor != _protocolVersion.minor || ![request->_URL isEqual: _URL] || ![request->_headers isEqual: _headers]) return false; if (request.remoteAddress != self.remoteAddress && | | | | | | | | | | | | | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | request->_protocolVersion.major != _protocolVersion.major || request->_protocolVersion.minor != _protocolVersion.minor || ![request->_URL isEqual: _URL] || ![request->_headers isEqual: _headers]) return false; if (request.remoteAddress != self.remoteAddress && !OFSocketAddressEqual(request.remoteAddress, self.remoteAddress)) return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAdd(&hash, _method); OFHashAdd(&hash, _protocolVersion.major); OFHashAdd(&hash, _protocolVersion.minor); OFHashAddHash(&hash, _URL.hash); OFHashAddHash(&hash, _headers.hash); if (_hasRemoteAddress) OFHashAddHash(&hash, OFSocketAddressHash(&_remoteAddress)); OFHashFinalize(&hash); return hash; } - (void)setProtocolVersion: (OFHTTPRequestProtocolVersion)protocolVersion { if (protocolVersion.major != 1 || protocolVersion.minor > 1) @throw [OFUnsupportedVersionException exceptionWithVersion: [OFString stringWithFormat: @"%hhu.%hhu", protocolVersion.major, protocolVersion.minor]]; _protocolVersion = protocolVersion; } - (OFHTTPRequestProtocolVersion)protocolVersion { return _protocolVersion; } - (void)setProtocolVersionString: (OFString *)string { void *pool = objc_autoreleasePoolPush(); OFArray *components = [string componentsSeparatedByString: @"."]; unsigned long long major, minor; OFHTTPRequestProtocolVersion protocolVersion; if (components.count != 2) @throw [OFInvalidFormatException exception]; major = [components.firstObject unsignedLongLongValue]; minor = [components.lastObject unsignedLongLongValue]; |
︙ | ︙ | |||
250 251 252 253 254 255 256 | _protocolVersion.major, _protocolVersion.minor]; } - (OFString *)description { void *pool = objc_autoreleasePoolPush(); | | | < | 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | _protocolVersion.major, _protocolVersion.minor]; } - (OFString *)description { void *pool = objc_autoreleasePoolPush(); const char *method = OFHTTPRequestMethodName(_method); OFString *indentedHeaders, *remoteAddress, *ret; indentedHeaders = [_headers.description stringByReplacingOccurrencesOfString: @"\n" withString: @"\n\t"]; if (_hasRemoteAddress) remoteAddress = OFSocketAddressString(&_remoteAddress); else remoteAddress = nil; ret = [[OFString alloc] initWithFormat: @"<%@:\n\tURL = %@\n" @"\tMethod = %s\n" @"\tHeaders = %@\n" |
︙ | ︙ |
Modified src/OFHTTPResponse.h from [91600eee28] to [b3d8087036].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFArray OF_GENERIC(ObjectType); /** * @class OFHTTPResponse OFHTTPResponse.h ObjFW/OFHTTPResponse.h * | | | | | | | | | > > > | | | | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | @class OFDictionary OF_GENERIC(KeyType, ObjectType); @class OFArray OF_GENERIC(ObjectType); /** * @class OFHTTPResponse OFHTTPResponse.h ObjFW/OFHTTPResponse.h * * @brief A class for representing an HTTP request response as a stream. */ @interface OFHTTPResponse: OFStream { OFHTTPRequestProtocolVersion _protocolVersion; short _statusCode; OFDictionary OF_GENERIC(OFString *, OFString *) *_headers; OF_RESERVE_IVARS(OFHTTPResponse, 4) } /** * @brief The protocol version of the HTTP request response. */ @property (nonatomic) OFHTTPRequestProtocolVersion protocolVersion; /** * @brief The protocol version of the HTTP request response as a string. */ @property (copy, nonatomic) OFString *protocolVersionString; /** * @brief The status code of the response to the HTTP request. */ @property (nonatomic) short statusCode; /** * @brief The headers of the response to the HTTP request. */ @property (copy, nonatomic) OFDictionary OF_GENERIC(OFString *, OFString *) *headers; /** * @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 */ - (OFString *)readString; /** * @brief Rread 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 */ - (OFString *)readStringWithEncoding: (OFStringEncoding)encoding; @end #ifdef __cplusplus extern "C" { #endif /** * @brief Returns a description string for the specified HTTP status code. * * @param code The HTTP status code to return a description string for * @return A description string for the specified HTTP status code */ extern OFString *_Nonnull OFHTTPStatusCodeString(short code); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFHTTPResponse.m from [4e1a4b346b] to [17a72a5d36].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
26 27 28 29 30 31 32 | #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedVersionException.h" OFString * | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedVersionException.h" OFString * OFHTTPStatusCodeString(short code) { switch (code) { case 100: return @"Continue"; case 101: return @"Switching Protocols"; case 200: |
︙ | ︙ | |||
114 115 116 117 118 119 120 | case 505: return @"HTTP Version Not Supported"; default: return @"(unknown)"; } } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | case 505: return @"HTTP Version Not Supported"; default: return @"(unknown)"; } } static OFStringEncoding encodingForContentType(OFString *contentType) { const char *UTF8String = contentType.UTF8String; size_t last, length = contentType.UTF8StringLength; enum { stateType, stateBeforeParamName, stateParamName, stateParamValueOrQuote, stateParamValue, stateParamQuotedValue, stateAfterParamValue } state = stateType; OFString *name = nil, *value = nil, *charset = nil; OFStringEncoding ret; last = 0; for (size_t i = 0; i < length; i++) { switch (state) { case stateType: if (UTF8String[i] == ';') { state = stateBeforeParamName; last = i + 1; } break; case stateBeforeParamName: if (UTF8String[i] == ' ') last = i + 1; else { state = stateParamName; i--; } break; case stateParamName: if (UTF8String[i] == '=') { name = [OFString stringWithUTF8String: UTF8String + last length: i - last]; state = stateParamValueOrQuote; last = i + 1; } break; case stateParamValueOrQuote: if (UTF8String[i] == '"') { state = stateParamQuotedValue; last = i + 1; } else { state = stateParamValue; i--; } break; case stateParamValue: if (UTF8String[i] == ';') { value = [OFString stringWithUTF8String: UTF8String + last length: i - last]; value = value.stringByDeletingTrailingWhitespaces; if ([name isEqual: @"charset"]) charset = value; state = stateBeforeParamName; last = i + 1; } break; case stateParamQuotedValue: if (UTF8String[i] == '"') { value = [OFString stringWithUTF8String: UTF8String + last length: i - last]; if ([name isEqual: @"charset"]) charset = value; state = stateAfterParamValue; } break; case stateAfterParamValue: if (UTF8String[i] == ';') { state = stateBeforeParamName; last = i + 1; } else if (UTF8String[i] != ' ') return OFStringEncodingAutodetect; break; } } if (state == stateParamValue) { value = [OFString stringWithUTF8String: UTF8String + last length: length - last]; value = value.stringByDeletingTrailingWhitespaces; if ([name isEqual: @"charset"]) charset = value; } @try { ret = OFStringEncodingParseName(charset); } @catch (OFInvalidArgumentException *e) { ret = OFStringEncodingAutodetect; } return ret; } @implementation OFHTTPResponse @synthesize statusCode = _statusCode, headers = _headers; |
︙ | ︙ | |||
247 248 249 250 251 252 253 | - (void)dealloc { [_headers release]; [super dealloc]; } | | | | | 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | - (void)dealloc { [_headers release]; [super dealloc]; } - (void)setProtocolVersion: (OFHTTPRequestProtocolVersion)protocolVersion { if (protocolVersion.major != 1 || protocolVersion.minor > 1) @throw [OFUnsupportedVersionException exceptionWithVersion: [OFString stringWithFormat: @"%hhu.%hhu", protocolVersion.major, protocolVersion.minor]]; _protocolVersion = protocolVersion; } - (OFHTTPRequestProtocolVersion)protocolVersion { return _protocolVersion; } - (void)setProtocolVersionString: (OFString *)string { void *pool = objc_autoreleasePoolPush(); OFArray *components = [string componentsSeparatedByString: @"."]; unsigned long long major, minor; OFHTTPRequestProtocolVersion protocolVersion; if (components.count != 2) @throw [OFInvalidFormatException exception]; major = [components.firstObject unsignedLongLongValue]; minor = [components.lastObject unsignedLongLongValue]; |
︙ | ︙ | |||
294 295 296 297 298 299 300 | - (OFString *)protocolVersionString { return [OFString stringWithFormat: @"%hhu.%hhu", _protocolVersion.major, _protocolVersion.minor]; } | | | | | | | | 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | - (OFString *)protocolVersionString { return [OFString stringWithFormat: @"%hhu.%hhu", _protocolVersion.major, _protocolVersion.minor]; } - (OFString *)readString { return [self readStringWithEncoding: OFStringEncodingAutodetect]; } - (OFString *)readStringWithEncoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); OFString *contentType, *contentLengthString, *ret; OFData *data; if (encoding == OFStringEncodingAutodetect && (contentType = [_headers objectForKey: @"Content-Type"]) != nil) encoding = encodingForContentType(contentType); if (encoding == OFStringEncodingAutodetect) encoding = OFStringEncodingUTF8; data = [self readDataUntilEndOfStream]; contentLengthString = [_headers objectForKey: @"Content-Length"]; if (contentLengthString != nil) { unsigned long long contentLength = contentLengthString.unsignedLongLongValue; |
︙ | ︙ |
Modified src/OFHTTPServer.h from [19c7df3c10] to [a2fd4b8141].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
62 63 64 65 66 67 68 | * connections will still be handled and you can start accepting new * connections again by calling @ref OFHTTPServer::start again. */ - (bool)server: (OFHTTPServer *)server didReceiveExceptionOnListeningSocket: (id)exception; /** | | > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | * connections will still be handled and you can start accepting new * connections again by calling @ref OFHTTPServer::start again. */ - (bool)server: (OFHTTPServer *)server didReceiveExceptionOnListeningSocket: (id)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 * an exception. * |
︙ | ︙ | |||
91 92 93 94 95 96 97 | * @brief A class for creating a simple HTTP server inside of applications. */ OF_SUBCLASSING_RESTRICTED @interface OFHTTPServer: OFObject { OFString *_Nullable _host; uint16_t _port; | < < < | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | * @brief A class for creating a simple HTTP server inside of applications. */ OF_SUBCLASSING_RESTRICTED @interface OFHTTPServer: OFObject { OFString *_Nullable _host; uint16_t _port; id <OFHTTPServerDelegate> _Nullable _delegate; OFString *_Nullable _name; OFTCPSocket *_Nullable _listeningSocket; #ifdef OF_HAVE_THREADS size_t _numberOfThreads, _nextThreadIndex; OFArray *_threadPool; #endif |
︙ | ︙ | |||
119 120 121 122 123 124 125 | * @brief The port on which the HTTP server will listen. * * Setting this after @ref start has been called raises an * @ref OFAlreadyConnectedException. */ @property (nonatomic) uint16_t port; | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | * @brief The port on which the HTTP server will listen. * * Setting this after @ref start has been called raises an * @ref OFAlreadyConnectedException. */ @property (nonatomic) uint16_t port; /** * @brief The delegate for the HTTP server. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id <OFHTTPServerDelegate> delegate; #ifdef OF_HAVE_THREADS |
︙ | ︙ |
Modified src/OFHTTPServer.m from [59a786282c] to [56dd1ea76e].
1 | /* | < < | > | | < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #include <stdlib.h> #include <string.h> #import "OFHTTPServer.h" #import "OFArray.h" #import "OFData.h" #import "OFDate.h" #import "OFDictionary.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" #import "OFNumber.h" #import "OFSocket+Private.h" #import "OFTCPSocket.h" #import "OFThread.h" #import "OFTimer.h" #import "OFURL.h" #import "OFAlreadyConnectedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" #import "OFWriteFailedException.h" /* * FIXME: Key normalization replaces headers like "DNT" with "Dnt". * FIXME: Errors are not reported to the user. */ @interface OFHTTPServer () <OFTCPSocketDelegate> @end |
︙ | ︙ | |||
75 76 77 78 79 80 81 | @interface OFHTTPServerConnection: OFObject <OFTCPSocketDelegate> { @public OFStreamSocket *_socket; OFHTTPServer *_server; OFTimer *_timer; enum { | | | | | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | @interface OFHTTPServerConnection: OFObject <OFTCPSocketDelegate> { @public OFStreamSocket *_socket; OFHTTPServer *_server; OFTimer *_timer; enum { stateAwaitingProlog, stateParsingHeaders, stateSendResponse } _state; uint8_t _HTTPMinorVersion; OFHTTPRequestMethod _method; OFString *_host, *_path; uint16_t _port; OFMutableDictionary *_headers; size_t _contentLength; OFStream *_requestBody; } |
︙ | ︙ | |||
117 118 119 120 121 122 123 | #ifdef OF_HAVE_THREADS OF_DIRECT_MEMBERS @interface OFHTTPServerThread: OFThread - (void)stop; @end #endif | | | < | < < | < | > | | > > > > > > | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | #ifdef OF_HAVE_THREADS OF_DIRECT_MEMBERS @interface OFHTTPServerThread: OFThread - (void)stop; @end #endif static OFString * normalizedKey(OFString *key) { char *cString = OFStrDup(key.UTF8String); unsigned char *tmp = (unsigned char *)cString; bool firstLetter = true; OFString *ret; while (*tmp != '\0') { if (!OFASCIIIsAlpha(*tmp)) { firstLetter = true; tmp++; continue; } *tmp = (firstLetter ? OFASCIIToUpper(*tmp) : OFASCIIToLower(*tmp)); firstLetter = false; tmp++; } @try { ret = [OFString stringWithUTF8StringNoCopy: cString freeWhenDone: true]; } @catch (id e) { OFFreeMemory(cString); @throw e; } return ret; } @implementation OFHTTPServerResponse - (instancetype)initWithSocket: (OFStreamSocket *)sock server: (OFHTTPServer *)server request: (OFHTTPRequest *)request { |
︙ | ︙ | |||
182 183 184 185 186 187 188 | void *pool = objc_autoreleasePoolPush(); OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; OFEnumerator *keyEnumerator, *valueEnumerator; OFString *key, *value; [_socket writeFormat: @"HTTP/%@ %hd %@\r\n", self.protocolVersionString, _statusCode, | | < | < | < | < | > | > > > > > > > | > | < | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | void *pool = objc_autoreleasePoolPush(); OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers; OFEnumerator *keyEnumerator, *valueEnumerator; OFString *key, *value; [_socket writeFormat: @"HTTP/%@ %hd %@\r\n", self.protocolVersionString, _statusCode, OFHTTPStatusCodeString(_statusCode)]; headers = [[_headers mutableCopy] autorelease]; if ([headers objectForKey: @"Date"] == nil) { OFString *date = [[OFDate date] dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; [headers setObject: date forKey: @"Date"]; } if ([headers objectForKey: @"Server"] == nil) { OFString *name = _server.name; if (name != nil) [headers setObject: name forKey: @"Server"]; } keyEnumerator = [headers keyEnumerator]; valueEnumerator = [headers objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (value = [valueEnumerator nextObject]) != nil) [_socket writeFormat: @"%@: %@\r\n", key, value]; [_socket writeString: @"\r\n"]; _headersSent = true; _chunked = [[headers objectForKey: @"Transfer-Encoding"] isEqual: @"chunked"]; objc_autoreleasePoolPop(pool); } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { /* TODO: Use non-blocking writes */ void *pool; if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (!_headersSent) [self of_sendHeaders]; 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); [_socket writeBuffer: buffer length: length]; [_socket writeString: @"\r\n"]; return length; } - (void)close { |
︙ | ︙ | |||
297 298 299 300 301 302 303 | _server = [server retain]; _timer = [[OFTimer scheduledTimerWithTimeInterval: 10 target: _socket selector: @selector( cancelAsyncRequests) repeats: false] retain]; | | | 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | _server = [server retain]; _timer = [[OFTimer scheduledTimerWithTimeInterval: 10 target: _socket selector: @selector( cancelAsyncRequests) repeats: false] retain]; _state = stateAwaitingProlog; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
331 332 333 334 335 336 337 | exception: (id)exception { if (line == nil || exception != nil) return false; @try { switch (_state) { | | | | | | | | | | | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 | exception: (id)exception { if (line == nil || exception != nil) return false; @try { switch (_state) { case stateAwaitingProlog: return [self parseProlog: line]; case stateParsingHeaders: return [self parseHeaders: line]; default: return false; } } @catch (OFWriteFailedException *e) { return false; } OFEnsure(0); } - (bool)parseProlog: (OFString *)line { OFString *method; OFMutableString *path; size_t pos; @try { OFString *version = [line substringWithRange: OFRangeMake(line.length - 9, 9)]; OFUnichar tmp; if (![version hasPrefix: @" HTTP/1."]) return [self sendErrorAndClose: 505]; tmp = [version characterAtIndex: 8]; if (tmp < '0' || tmp > '9') return [self sendErrorAndClose: 400]; _HTTPMinorVersion = (uint8_t)(tmp - '0'); } @catch (OFOutOfRangeException *e) { return [self sendErrorAndClose: 400]; } pos = [line rangeOfString: @" "].location; if (pos == OFNotFound) return [self sendErrorAndClose: 400]; method = [line substringToIndex: pos]; @try { _method = OFHTTPRequestMethodParseName(method); } @catch (OFInvalidArgumentException *e) { return [self sendErrorAndClose: 405]; } @try { OFRange range = OFRangeMake(pos + 1, line.length - pos - 10); path = [[[line substringWithRange: range] mutableCopy] autorelease]; } @catch (OFOutOfRangeException *e) { return [self sendErrorAndClose: 400]; } [path deleteEnclosingWhitespaces]; [path makeImmutable]; if (![path hasPrefix: @"/"]) return [self sendErrorAndClose: 400]; _headers = [[OFMutableDictionary alloc] init]; _path = [path copy]; _state = stateParsingHeaders; return true; } - (bool)parseHeaders: (OFString *)line { OFString *key, *value, *old; |
︙ | ︙ | |||
438 439 440 441 442 443 444 | contentLength: contentLength]; [_timer invalidate]; [_timer release]; _timer = nil; } | | | | < | < | | | 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 | contentLength: contentLength]; [_timer invalidate]; [_timer release]; _timer = nil; } _state = stateSendResponse; [self createResponse]; return false; } pos = [line rangeOfString: @":"].location; if (pos == OFNotFound) return [self sendErrorAndClose: 400]; key = [line substringToIndex: pos]; value = [line substringFromIndex: pos + 1]; key = normalizedKey(key.stringByDeletingTrailingWhitespaces); value = value.stringByDeletingLeadingWhitespaces; old = [_headers objectForKey: key]; if (old != nil) value = [old stringByAppendingFormat: @",%@", value]; [_headers setObject: value forKey: key]; if ([key isEqual: @"Host"]) { pos = [value rangeOfString: @":" options: OFStringSearchBackwards].location; if (pos != OFNotFound) { [_host release]; _host = [[value substringToIndex: pos] retain]; @try { unsigned long long portTmp = [value substringFromIndex: pos + 1] .unsignedLongLongValue; |
︙ | ︙ | |||
496 497 498 499 500 501 502 | return true; } - (bool)sendErrorAndClose: (short)statusCode { OFString *date = [[OFDate date] dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; | < | < < | 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 | return true; } - (bool)sendErrorAndClose: (short)statusCode { OFString *date = [[OFDate date] dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"]; [_socket writeFormat: @"HTTP/1.1 %hd %@\r\n" @"Date: %@\r\n" @"Server: %@\r\n" @"\r\n", statusCode, OFHTTPStatusCodeString(statusCode), date, _server.name]; return false; } - (void)createResponse { void *pool = objc_autoreleasePoolPush(); OFMutableURL *URL; |
︙ | ︙ | |||
537 538 539 540 541 542 543 | URL = [OFMutableURL URL]; URL.scheme = @"http"; URL.host = _host; if (_port != 80) URL.port = [OFNumber numberWithUnsignedShort: _port]; | > | > | | | | | | | > > > > > | | 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 | URL = [OFMutableURL URL]; URL.scheme = @"http"; URL.host = _host; if (_port != 80) URL.port = [OFNumber numberWithUnsignedShort: _port]; @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; request.protocolVersion = (OFHTTPRequestProtocolVersion){ 1, _HTTPMinorVersion }; request.headers = _headers; request.remoteAddress = _socket.remoteAddress; response = [[[OFHTTPServerResponse alloc] initWithSocket: _socket server: _server request: request] autorelease]; |
︙ | ︙ | |||
609 610 611 612 613 614 615 | } - (bool)lowlevelIsAtEndOfStream { return _atEndOfStream; } | | < | < | < | < | < < | | | 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 | } - (bool)lowlevelIsAtEndOfStream { return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { if (_socket == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) return 0; if (_socket.atEndOfStream) @throw [OFTruncatedDataException exception]; /* Content-Length */ if (!_chunked) { size_t ret; if (length > (unsigned long long)_toRead) length = (size_t)_toRead; ret = [_socket readIntoBuffer: buffer length: length]; _toRead -= ret; if (_toRead == 0) _atEndOfStream = true; return ret; } /* Chunked */ if (_toRead == -2) { char tmp[2]; switch ([_socket readIntoBuffer: tmp length: 2]) { case 2: _toRead++; if (tmp[1] != '\n') @throw [OFInvalidFormatException exception]; case 1: _toRead++; if (tmp[0] != '\r') @throw [OFInvalidFormatException exception]; } if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead == -1) { char tmp; if ([_socket readIntoBuffer: &tmp length: 1] == 1) { _toRead++; if (tmp != '\n') @throw [OFInvalidFormatException exception]; } if (_setAtEndOfStream && _toRead == 0) _atEndOfStream = true; return 0; } else if (_toRead > 0) { if (length > (unsigned long long)_toRead) length = (size_t)_toRead; length = [_socket readIntoBuffer: buffer length: length]; _toRead -= length; if (_toRead == 0) _toRead = -2; return length; } else { void *pool = objc_autoreleasePoolPush(); OFString *line; size_t pos; unsigned long long toRead; @try { line = [_socket tryReadLine]; } @catch (OFInvalidEncodingException *e) { @throw [OFInvalidFormatException exception]; } if (line == nil) return 0; pos = [line rangeOfString: @";"].location; if (pos != OFNotFound) line = [line substringToIndex: pos]; if (line.length < 1) { /* * We have read the empty string because the socket is * at end of stream. */ if (_socket.atEndOfStream && pos == OFNotFound) @throw [OFTruncatedDataException exception]; else @throw [OFInvalidFormatException exception]; } toRead = [line unsignedLongLongValueWithBase: 16]; if (toRead > LLONG_MAX) |
︙ | ︙ | |||
826 827 828 829 830 831 832 | } - (uint16_t)port { return _port; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 824 825 826 827 828 829 830 831 832 833 834 835 836 837 | } - (uint16_t)port { return _port; } #ifdef OF_HAVE_THREADS - (void)setNumberOfThreads: (size_t)numberOfThreads { if (numberOfThreads == 0) @throw [OFInvalidArgumentException exception]; if (_listeningSocket != nil) |
︙ | ︙ | |||
914 915 916 917 918 919 920 | if (_host == nil) @throw [OFInvalidArgumentException exception]; if (_listeningSocket != nil) @throw [OFAlreadyConnectedException exception]; | < < < < < < < < < < < < < | < | < | 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 | if (_host == nil) @throw [OFInvalidArgumentException exception]; if (_listeningSocket != nil) @throw [OFAlreadyConnectedException exception]; _listeningSocket = [[OFTCPSocket alloc] init]; _port = [_listeningSocket bindToHost: _host port: _port]; [_listeningSocket listen]; #ifdef OF_HAVE_THREADS if (_numberOfThreads > 1) { OFMutableArray *threads = [OFMutableArray arrayWithCapacity: _numberOfThreads - 1]; |
︙ | ︙ | |||
992 993 994 995 996 997 998 | exception: (id)exception { if (exception != nil) { if (![_delegate respondsToSelector: @selector(server:didReceiveExceptionOnListeningSocket:)]) return false; | | | 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 | exception: (id)exception { if (exception != nil) { if (![_delegate respondsToSelector: @selector(server:didReceiveExceptionOnListeningSocket:)]) return false; return [_delegate server: self didReceiveExceptionOnListeningSocket: exception]; } #ifdef OF_HAVE_THREADS if (_numberOfThreads > 1) { OFHTTPServerThread *thread = [_threadPool objectAtIndex: _nextThreadIndex]; |
︙ | ︙ |
Modified src/OFHTTPURLHandler.h from [93af9fbb1c] to [6b4755acdc].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFHTTPURLHandler.m from [b01378202f] to [c4a43aad17].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFHostAddressResolver.h from [51f39b12b0] to [5c6783fd03].
1 | /* | < < | < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFDNSResolver.h" #import "OFRunLoop.h" #import "OFSocket.h" OF_ASSUME_NONNULL_BEGIN @class OFDNSResolverSettings; @class OFDNSResourceRecord; @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableData; @class OFString; @interface OFHostAddressResolver: OFObject <OFDNSResolverQueryDelegate> { OFString *_host; OFSocketAddressFamily _addressFamily; OFDNSResolver *_resolver; OFDNSResolverSettings *_settings; OFRunLoopMode _Nullable _runLoopMode; id <OFDNSResolverHostDelegate> _Nullable _delegate; bool _isFQDN; size_t _searchDomainIndex; unsigned int _numExpectedResponses; OFMutableData *_addresses; } - (instancetype)initWithHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily resolver: (OFDNSResolver *)resolver settings: (OFDNSResolverSettings *)settings runLoopMode: (nullable OFRunLoopMode)runLoopMode delegate: (nullable id <OFDNSResolverHostDelegate>)delegate; - (void)asyncResolve; - (OFData *)resolve; @end OF_ASSUME_NONNULL_END |
Modified src/OFHostAddressResolver.m from [1663ef2651] to [3275d58c93].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
38 39 40 41 42 43 44 | @public bool _done; OFData *_addresses; id _exception; } @end | | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | @public bool _done; OFData *_addresses; id _exception; } @end static const OFRunLoopMode resolveRunLoopMode = @"OFHostAddressResolverResolveRunLoopMode"; static bool isFQDN(OFString *host, unsigned int minNumberOfDotsInAbsoluteName) { const char *UTF8String; size_t length; unsigned int dots; |
︙ | ︙ | |||
64 65 66 67 68 69 70 | dots++; return (dots >= minNumberOfDotsInAbsoluteName); } static bool addressForRecord(OF_KINDOF(OFDNSResourceRecord *) record, | | < | | | | | | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | dots++; return (dots >= minNumberOfDotsInAbsoluteName); } static bool addressForRecord(OF_KINDOF(OFDNSResourceRecord *) record, const OFSocketAddress **address, OFSocketAddressFamily addressFamily) { switch ([record recordType]) { #ifdef OF_HAVE_IPV6 case OFDNSRecordTypeAAAA: if (addressFamily != OFSocketAddressFamilyIPv6 && addressFamily != OFSocketAddressFamilyAny) return false; break; #endif case OFDNSRecordTypeA: if (addressFamily != OFSocketAddressFamilyIPv4 && addressFamily != OFSocketAddressFamilyAny) return false; break; default: return false; } *address = [record address]; return true; } static void callDelegateInMode(OFRunLoopMode runLoopMode, id <OFDNSResolverHostDelegate> delegate, OFDNSResolver *resolver, OFString *host, OFData *addresses, id exception) { SEL selector = @selector(resolver:didResolveHost:addresses:exception:); if ([delegate respondsToSelector: selector]) { OFTimer *timer = [OFTimer |
︙ | ︙ | |||
112 113 114 115 116 117 118 | [[OFRunLoop currentRunLoop] addTimer: timer forMode: runLoopMode]; } } @implementation OFHostAddressResolver: OFObject - (instancetype)initWithHost: (OFString *)host | | | | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | [[OFRunLoop currentRunLoop] addTimer: timer forMode: runLoopMode]; } } @implementation OFHostAddressResolver: OFObject - (instancetype)initWithHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily resolver: (OFDNSResolver *)resolver settings: (OFDNSResolverSettings *)settings runLoopMode: (OFRunLoopMode)runLoopMode delegate: (id <OFDNSResolverHostDelegate>)delegate { self = [super init]; @try { _host = [host copy]; _addressFamily = addressFamily; |
︙ | ︙ | |||
161 162 163 164 165 166 167 | domainName = [OFString stringWithFormat: @"%@.%@", _host, searchDomain]; } else domainName = _host; #ifdef OF_HAVE_IPV6 | | | | | | | | | | | | | | | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | domainName = [OFString stringWithFormat: @"%@.%@", _host, searchDomain]; } else domainName = _host; #ifdef OF_HAVE_IPV6 if (_addressFamily == OFSocketAddressFamilyIPv6 || _addressFamily == OFSocketAddressFamilyAny) { OFDNSQuery *query = [OFDNSQuery queryWithDomainName: domainName DNSClass: OFDNSClassIN recordType: OFDNSRecordTypeAAAA]; _numExpectedResponses++; [_resolver asyncPerformQuery: query runLoopMode: _runLoopMode delegate: self]; } #endif if (_addressFamily == OFSocketAddressFamilyIPv4 || _addressFamily == OFSocketAddressFamilyAny) { OFDNSQuery *query = [OFDNSQuery queryWithDomainName: domainName DNSClass: OFDNSClassIN recordType: OFDNSRecordTypeA]; _numExpectedResponses++; [_resolver asyncPerformQuery: query runLoopMode: _runLoopMode delegate: self]; } } - (void)resolver: (OFDNSResolver *)resolver didPerformQuery: (OFDNSQuery *)query response: (OFDNSResponse *)response exception: (id)exception { _numExpectedResponses--; if ([exception isKindOfClass: [OFDNSQueryFailedException class]] && [exception errorCode] == OFDNSResolverErrorCodeServerNameError && !_isFQDN && _numExpectedResponses == 0 && _addresses.count == 0 && _searchDomainIndex + 1 < _settings->_searchDomains.count) { _searchDomainIndex++; [self sendQueries]; return; } for (OF_KINDOF(OFDNSResourceRecord *) record in [response.answerRecords objectForKey: query.domainName]) { const OFSocketAddress *address = NULL; OFDNSQuery *CNAMEQuery; if ([record DNSClass] != OFDNSClassIN) continue; if (addressForRecord(record, &address, _addressFamily)) { [_addresses addItem: address]; continue; } if ([record recordType] != OFDNSRecordTypeCNAME) continue; /* FIXME: Check if it's already in answers */ CNAMEQuery = [OFDNSQuery queryWithDomainName: [record alias] DNSClass: OFDNSClassIN recordType: query.recordType]; _numExpectedResponses++; [_resolver asyncPerformQuery: CNAMEQuery runLoopMode: _runLoopMode delegate: self]; } |
︙ | ︙ | |||
243 244 245 246 247 248 249 | _addresses = nil; if ([exception isKindOfClass: [OFDNSQueryFailedException class]]) exception = [OFResolveHostFailedException exceptionWithHost: _host addressFamily: _addressFamily | | | | < | > | < | | | | | | | < | < < < | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | _addresses = nil; if ([exception isKindOfClass: [OFDNSQueryFailedException class]]) exception = [OFResolveHostFailedException exceptionWithHost: _host addressFamily: _addressFamily errorCode: [exception errorCode]]; if (exception == nil) exception = [OFResolveHostFailedException exceptionWithHost: _host addressFamily: _addressFamily errorCode: OFDNSResolverErrorCodeNoResult]; } else exception = nil; if ([_delegate respondsToSelector: @selector(resolver:didResolveHost:addresses:exception:)]) [_delegate resolver: _resolver didResolveHost: _host addresses: _addresses exception: exception]; } - (void)asyncResolve { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC(OFString *) *aliases; @try { OFSocketAddress address = OFSocketAddressParseIP(_host, 0); OFData *addresses = nil; id exception = nil; if (_addressFamily == address.family || _addressFamily == OFSocketAddressFamilyAny) addresses = [OFData dataWithItems: &address count: 1 itemSize: sizeof(address)]; else exception = [OFInvalidArgumentException exception]; callDelegateInMode(_runLoopMode, _delegate, _resolver, _host, addresses, exception); objc_autoreleasePoolPop(pool); return; } @catch (OFInvalidFormatException *e) { } if ((aliases = [_settings->_staticHosts objectForKey: _host]) != nil) { OFMutableData *addresses = [OFMutableData dataWithItemSize: sizeof(OFSocketAddress)]; id exception = nil; for (OFString *alias in aliases) { OFSocketAddress address; @try { address = OFSocketAddressParseIP(alias, 0); } @catch (OFInvalidFormatException *e) { continue; } if (_addressFamily != address.family && _addressFamily != OFSocketAddressFamilyAny) continue; [addresses addItem: &address]; } [addresses makeImmutable]; if (addresses.count == 0) { addresses = nil; exception = [OFResolveHostFailedException exceptionWithHost: _host addressFamily: _addressFamily errorCode: OFDNSResolverErrorCodeNoResult]; } callDelegateInMode(_runLoopMode, _delegate, _resolver, _host, addresses, exception); objc_autoreleasePoolPop(pool); return; } _isFQDN = isFQDN(_host, _settings->_minNumberOfDotsInAbsoluteName); _addresses = [[OFMutableData alloc] initWithItemSize: sizeof(OFSocketAddress)]; [self sendQueries]; objc_autoreleasePoolPop(pool); } - (OFData *)resolve { void *pool = objc_autoreleasePoolPush(); OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; OFHostAddressResolverDelegate *delegate; OFData *ret; delegate = [[[OFHostAddressResolverDelegate alloc] init] autorelease]; _runLoopMode = [resolveRunLoopMode copy]; _delegate = [delegate retain]; [self asyncResolve]; while (!delegate->_done) [runLoop runMode: resolveRunLoopMode beforeDate: nil]; /* Cleanup */ [runLoop runMode: resolveRunLoopMode beforeDate: [OFDate date]]; if (delegate->_exception != nil) @throw delegate->_exception; ret = [delegate->_addresses copy]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end @implementation OFHostAddressResolverDelegate - (void)dealloc { |
︙ | ︙ |
Renamed and modified src/huffman_tree.h [bf284ca06e] to src/OFHuffmanTree.h [0152a399af].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #import "macros.h" #import "OFInvalidFormatException.h" OF_ASSUME_NONNULL_BEGIN | | | | > | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #import "macros.h" #import "OFInvalidFormatException.h" OF_ASSUME_NONNULL_BEGIN typedef struct _OFHuffmanTree { struct _OFHuffmanTree *_Nullable leaves[2]; uint16_t value; } *OFHuffmanTree; /* Inlined for performance. */ static OF_INLINE bool OFHuffmanTreeWalk(id _Nullable stream, bool (*bitReader)(id _Nullable, uint16_t *_Nonnull, uint8_t), OFHuffmanTree _Nonnull *_Nonnull tree, uint16_t *_Nonnull value) { OFHuffmanTree iter = *tree; uint16_t bits; while (iter->value == 0xFFFF) { if OF_UNLIKELY (!bitReader(stream, &bits, 1)) { *tree = iter; return false; } |
︙ | ︙ | |||
52 53 54 55 56 57 58 | *value = iter->value; return true; } #ifdef __cplusplus extern "C" { #endif | < | < | > | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | *value = iter->value; return true; } #ifdef __cplusplus extern "C" { #endif extern OFHuffmanTree _Nonnull OFHuffmanTreeNew(uint8_t lengths[_Nonnull], uint16_t count); extern OFHuffmanTree _Nonnull OFHuffmanTreeNewSingle(uint16_t value); extern void OFHuffmanTreeFree(OFHuffmanTree _Nonnull tree); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Renamed and modified src/huffman_tree.m [c3ebe65312] to src/OFHuffmanTree.m [13f0a946b0].
1 | /* | < < | | | | | | < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdint.h> #include <stdlib.h> #import "OFHuffmanTree.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" static OFHuffmanTree newTree(void) { OFHuffmanTree tree; tree = OFAllocMemory(1, sizeof(*tree)); tree->leaves[0] = tree->leaves[1] = NULL; tree->value = 0xFFFF; return tree; } static void treeInsert(OFHuffmanTree tree, uint16_t code, uint8_t length, uint16_t value) { while (length > 0) { uint8_t bit; length--; bit = (code & (1u << length)) >> length; if (tree->leaves[bit] == NULL) tree->leaves[bit] = newTree(); tree = tree->leaves[bit]; } tree->value = value; } OFHuffmanTree OFHuffmanTreeNew(uint8_t lengths[], uint16_t count) { OFHuffmanTree tree; uint16_t *lengthCount = NULL; uint16_t code, maxCode = 0, *nextCode = NULL; uint_fast8_t maxBit = 0; @try { for (uint16_t i = 0; i < count; i++) { uint_fast8_t length = lengths[i]; if OF_UNLIKELY (length > maxBit) { lengthCount = OFResizeMemory(lengthCount, length + 1, sizeof(uint16_t)); nextCode = OFResizeMemory(nextCode, length + 1, sizeof(uint16_t)); for (uint_fast8_t j = maxBit + 1; j <= length; j++) { lengthCount[j] = 0; nextCode[j] = 0; } |
︙ | ︙ | |||
97 98 99 100 101 102 103 | tree = newTree(); for (uint16_t i = 0; i <= maxCode; i++) { uint8_t length = lengths[i]; if (length > 0) | | | | | | | | | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | tree = newTree(); for (uint16_t i = 0; i <= maxCode; i++) { uint8_t length = lengths[i]; if (length > 0) treeInsert(tree, nextCode[length]++, length, i); } } @finally { OFFreeMemory(lengthCount); OFFreeMemory(nextCode); } return tree; } OFHuffmanTree OFHuffmanTreeNewSingle(uint16_t value) { OFHuffmanTree tree = newTree(); tree->value = value; return tree; } void OFHuffmanTreeFree(OFHuffmanTree tree) { for (uint_fast8_t i = 0; i < 2; i++) if OF_LIKELY (tree->leaves[i] != NULL) OFHuffmanTreeFree(tree->leaves[i]); OFFreeMemory(tree); } |
Modified src/OFINICategory+Private.h from [daec4f9da8] to [6b757dc025].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | @class OFStream; OF_DIRECT_MEMBERS @interface OFINICategory () - (instancetype)of_initWithName: (OFString *)name OF_METHOD_FAMILY(init); - (void)of_parseLine: (OFString *)line; - (bool)of_writeToStream: (OFStream *)stream | | | 21 22 23 24 25 26 27 28 29 30 31 32 | @class OFStream; OF_DIRECT_MEMBERS @interface OFINICategory () - (instancetype)of_initWithName: (OFString *)name OF_METHOD_FAMILY(init); - (void)of_parseLine: (OFString *)line; - (bool)of_writeToStream: (OFStream *)stream encoding: (OFStringEncoding)encoding first: (bool)first; @end OF_ASSUME_NONNULL_END |
Modified src/OFINICategory.h from [0c961c5344] to [e194c2c9e1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
39 40 41 42 43 44 45 | * @brief The name of the INI category */ @property (copy, nonatomic) OFString *name; - (instancetype)init OF_UNAVAILABLE; /** | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | < | | | | | | | | < | | | | | | | < | | | | < | | | | | < | | | | < | | | | < | | | | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | * @brief The name of the INI category */ @property (copy, nonatomic) OFString *name; - (instancetype)init OF_UNAVAILABLE; /** * @brief Returns the string for the specified key, or `nil` if it does not * exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the string should be returned * @return The string for the specified key, or `nil` if it does not exist */ - (nullable OFString *)stringForKey: (OFString *)key; /** * @brief Returns the string for the specified key or the specified default * value if it does not exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the string should be returned * @param defaultValue The value to return if the key does not exist * @return The string for the specified key or the specified default value if * it does not exist */ - (nullable OFString *)stringForKey: (OFString *)key defaultValue: (nullable OFString *)defaultValue; /** * @brief Returns the long long for the specified key or the specified default * value if it does not exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the long long should be returned * @param defaultValue The value to return if the key does not exist * @return The long long for the specified key or the specified default value * if it does not exist */ - (long long)longLongForKey: (OFString *)key defaultValue: (long long)defaultValue; /** * @brief Returns the bool for the specified key or the specified default value * if it does not exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the bool should be returned * @param defaultValue The value to return if the key does not exist * @return The bool for the specified key or the specified default value if it * does not exist */ - (bool)boolForKey: (OFString *)key defaultValue: (bool)defaultValue; /** * @brief Returns the float for the specified key or the specified default * value if it does not exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the float should be returned * @param defaultValue The value to return if the key does not exist * @return The float for the specified key or the specified default value if it * does not exist */ - (float)floatForKey: (OFString *)key defaultValue: (float)defaultValue; /** * @brief Returns the double for the specified key or the specified default * value if it does not exist. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is returned. * * @param key The key for which the double should be returned * @param defaultValue The value to return if the key does not exist * @return The double for the specified key or the specified default value if * it does not exist */ - (double)doubleForKey: (OFString *)key defaultValue: (double)defaultValue; /** * @brief Returns an array of strings for the specified multi-key, or an empty * array if the key does not exist. * * A multi-key is a key which exists several times in the same category. Each * occurrence of the key/value pair adds the respective value to the array. * * @param key The multi-key for which the array should be returned * @return The array for the specified key, or an empty array if it does not * exist */ - (OFArray OF_GENERIC(OFString *) *)stringArrayForKey: (OFString *)key; /** * @brief Sets the value of the specified key to the specified string. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is changed. * * @param string The string to which the key should be set * @param key The key for which the new value should be set */ - (void)setString: (OFString *)string forKey: (OFString *)key; /** * @brief Sets the value of the specified key to the specified long long. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is changed. * * @param longLong The long long to which the key should be set * @param key The key for which the new value should be set */ - (void)setLongLong: (long long)longLong forKey: (OFString *)key; /** * @brief Sets the value of the specified key to the specified bool. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is changed. * * @param bool_ The bool to which the key should be set * @param key The key for which the new value should be set */ - (void)setBool: (bool)bool_ forKey: (OFString *)key; /** * @brief Sets the value of the specified key to the specified float. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is changed. * * @param float_ The float to which the key should be set * @param key The key for which the new value should be set */ - (void)setFloat: (float)float_ forKey: (OFString *)key; /** * @brief Sets the value of the specified key to the specified double. * * If the specified key is a multi-key (see @ref stringArrayForKey:), the value * of the first key/value pair found is changed. * * @param double_ The double to which the key should be set * @param key The key for which the new value should be set */ - (void)setDouble: (double)double_ forKey: (OFString *)key; /** * @brief Sets the specified multi-key to the specified array of strings. * * It replaces the first occurrence of the multi-key with several key/value * pairs and removes all following occurrences. If the multi-key does not exist * yet, it is appended to the section. * * See also @ref stringArrayForKey: for more information about multi-keys. * * @param array The array of strings to which the multi-key should be set * @param key The multi-key for which the new values should be set */ - (void)setStringArray: (OFArray OF_GENERIC(OFString *) *)array forKey: (OFString *)key; /** * @brief Removes the value for the specified key * * If the specified key is a multi-key (see @ref stringArrayForKey:), all * key/value pairs matching the specified key are removed. * * @param key The key of the value to remove */ - (void)removeValueForKey: (OFString *)key; @end OF_ASSUME_NONNULL_END |
Modified src/OFINICategory.m from [ee9139e5e6] to [0938799665].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
50 51 52 53 54 55 56 | ![string hasPrefix: @"\f"] && ![string hasSuffix: @" "] && ![string hasSuffix: @"\t"] && ![string hasSuffix: @"\f"] && ![string containsString: @"\""]) return string; mutableString = [[string mutableCopy] autorelease]; | | < | < | < | < | < | | < | < | < | < | < > > > > > > > > > > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | ![string hasPrefix: @"\f"] && ![string hasSuffix: @" "] && ![string hasSuffix: @"\t"] && ![string hasSuffix: @"\f"] && ![string containsString: @"\""]) return string; mutableString = [[string mutableCopy] autorelease]; [mutableString replaceOccurrencesOfString: @"\\" withString: @"\\\\"]; [mutableString replaceOccurrencesOfString: @"\f" withString: @"\\f"]; [mutableString replaceOccurrencesOfString: @"\r" withString: @"\\r"]; [mutableString replaceOccurrencesOfString: @"\n" withString: @"\\n"]; [mutableString replaceOccurrencesOfString: @"\"" withString: @"\\\""]; [mutableString prependString: @"\""]; [mutableString appendString: @"\""]; [mutableString makeImmutable]; return mutableString; } static OFString * unescapeString(OFString *string) { OFMutableString *mutableString; if (![string hasPrefix: @"\""] || ![string hasSuffix: @"\""]) return string; string = [string substringWithRange: OFRangeMake(1, string.length - 2)]; mutableString = [[string mutableCopy] autorelease]; [mutableString replaceOccurrencesOfString: @"\\f" withString: @"\f"]; [mutableString replaceOccurrencesOfString: @"\\r" withString: @"\r"]; [mutableString replaceOccurrencesOfString: @"\\n" withString: @"\n"]; [mutableString replaceOccurrencesOfString: @"\\\"" withString: @"\""]; [mutableString replaceOccurrencesOfString: @"\\\\" withString: @"\\"]; [mutableString makeImmutable]; return mutableString; } @implementation OFINICategoryPair - (void)dealloc { [_key release]; [_value release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"%@ = %@", _key, _value]; } @end @implementation OFINICategoryComment - (void)dealloc { [_comment release]; [super dealloc]; } - (OFString *)description { return [[_comment copy] autorelease]; } @end @implementation OFINICategory @synthesize name = _name; - (instancetype)of_initWithName: (OFString *)name OF_DIRECT { |
︙ | ︙ | |||
154 155 156 157 158 159 160 | { if (![line hasPrefix: @";"]) { OFINICategoryPair *pair = [[[OFINICategoryPair alloc] init] autorelease]; OFString *key, *value; size_t pos; | | | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | { if (![line hasPrefix: @";"]) { OFINICategoryPair *pair = [[[OFINICategoryPair alloc] init] autorelease]; OFString *key, *value; size_t pos; if ((pos = [line rangeOfString: @"="].location) == OFNotFound) @throw [OFInvalidFormatException exception]; key = unescapeString([line substringToIndex: pos] .stringByDeletingEnclosingWhitespaces); value = unescapeString([line substringFromIndex: pos + 1] .stringByDeletingEnclosingWhitespaces); |
︙ | ︙ | |||
178 179 180 181 182 183 184 | [_lines addObject: comment]; } } - (OFString *)stringForKey: (OFString *)key { | | < | | | < | < | < | < | < | < | < | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | [_lines addObject: comment]; } } - (OFString *)stringForKey: (OFString *)key { return [self stringForKey: key defaultValue: nil]; } - (OFString *)stringForKey: (OFString *)key defaultValue: (OFString *)defaultValue { for (id line in _lines) { OFINICategoryPair *pair; if (![line isKindOfClass: [OFINICategoryPair class]]) continue; pair = line; if ([pair->_key isEqual: key]) return [[pair->_value copy] autorelease]; } return defaultValue; } - (long long)longLongForKey: (OFString *)key defaultValue: (long long)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *value = [self stringForKey: key defaultValue: nil]; long long ret; if (value != nil) ret = [value longLongValueWithBase: 0]; else ret = defaultValue; objc_autoreleasePoolPop(pool); return ret; } - (bool)boolForKey: (OFString *)key defaultValue: (bool)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *value = [self stringForKey: key defaultValue: nil]; bool ret; if (value != nil) { if ([value isEqual: @"true"]) ret = true; else if ([value isEqual: @"false"]) ret = false; else @throw [OFInvalidFormatException exception]; } else ret = defaultValue; objc_autoreleasePoolPop(pool); return ret; } - (float)floatForKey: (OFString *)key defaultValue: (float)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *value = [self stringForKey: key defaultValue: nil]; float ret; if (value != nil) ret = value.floatValue; else ret = defaultValue; objc_autoreleasePoolPop(pool); return ret; } - (double)doubleForKey: (OFString *)key defaultValue: (double)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *value = [self stringForKey: key defaultValue: nil]; double ret; if (value != nil) ret = value.doubleValue; else ret = defaultValue; objc_autoreleasePoolPop(pool); return ret; } - (OFArray OF_GENERIC(OFString *) *)stringArrayForKey: (OFString *)key { OFMutableArray *ret = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); for (id line in _lines) { OFINICategoryPair *pair; |
︙ | ︙ | |||
301 302 303 304 305 306 307 | objc_autoreleasePoolPop(pool); [ret makeImmutable]; return ret; } | | < | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | objc_autoreleasePoolPop(pool); [ret makeImmutable]; return ret; } - (void)setString: (OFString *)string forKey: (OFString *)key { void *pool = objc_autoreleasePoolPush(); OFINICategoryPair *pair; for (id line in _lines) { if (![line isKindOfClass: [OFINICategoryPair class]]) continue; |
︙ | ︙ | |||
342 343 344 345 346 347 348 | @throw e; } objc_autoreleasePoolPop(pool); } | < | | | < | < | < | < | | | | | | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | @throw e; } objc_autoreleasePoolPop(pool); } - (void)setLongLong: (long long)longLong forKey: (OFString *)key { void *pool = objc_autoreleasePoolPush(); [self setString: [OFString stringWithFormat: @"%lld", longLong] forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setBool: (bool)bool_ forKey: (OFString *)key { [self setString: (bool_ ? @"true" : @"false") forKey: key]; } - (void)setFloat: (float)float_ forKey: (OFString *)key { void *pool = objc_autoreleasePoolPush(); [self setString: [OFString stringWithFormat: @"%g", float_] forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setDouble: (double)double_ forKey: (OFString *)key { void *pool = objc_autoreleasePoolPush(); [self setString: [OFString stringWithFormat: @"%g", double_] forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setStringArray: (OFArray OF_GENERIC(OFString *) *)array forKey: (OFString *)key { void *pool; OFMutableArray *pairs; id const *lines; size_t count; bool replaced; if (array.count == 0) { [self removeValueForKey: key]; return; } pool = objc_autoreleasePoolPush(); pairs = [OFMutableArray arrayWithCapacity: array.count]; for (OFString *string in array) { OFINICategoryPair *pair; if (![string isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; pair = [[[OFINICategoryPair alloc] init] autorelease]; pair->_key = [key copy]; pair->_value = [string copy]; [pairs addObject: pair]; } lines = _lines.objects; count = _lines.count; replaced = false; |
︙ | ︙ | |||
480 481 482 483 484 485 486 | } } objc_autoreleasePoolPop(pool); } - (bool)of_writeToStream: (OFStream *)stream | | < | < > > > > > > | 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | } } objc_autoreleasePoolPop(pool); } - (bool)of_writeToStream: (OFStream *)stream encoding: (OFStringEncoding)encoding first: (bool)first { if (_lines.count == 0) return false; if (first) [stream writeFormat: @"[%@]\r\n", _name]; else [stream writeFormat: @"\r\n[%@]\r\n", _name]; for (id line in _lines) { if ([line isKindOfClass: [OFINICategoryComment class]]) { OFINICategoryComment *comment = line; [stream writeFormat: @"%@\r\n", comment->_comment]; } else if ([line isKindOfClass: [OFINICategoryPair class]]) { OFINICategoryPair *pair = line; OFString *key = escapeString(pair->_key); OFString *value = escapeString(pair->_value); OFString *tmp = [OFString stringWithFormat: @"%@=%@\r\n", key, value]; [stream writeString: tmp encoding: encoding]; } else @throw [OFInvalidArgumentException exception]; } return true; } - (OFString *)description { return [OFString stringWithFormat: @"<%@ \"%@\": %@>", self.class, _name, _lines]; } @end |
Modified src/OFINIFile.h from [c3c19039f7] to [85f822e023].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | */ OF_SUBCLASSING_RESTRICTED @interface OFINIFile: OFObject { OFMutableArray OF_GENERIC(OFINICategory *) *_categories; } /** * @brief Creates a new OFINIFile with the contents of the specified file. * * @param path The path to the file whose contents the OFINIFile should contain * * @return A new, autoreleased OFINIFile with the contents of the specified file */ + (instancetype)fileWithPath: (OFString *)path; /** * @brief Creates a new OFINIFile with the contents of the specified file in * the specified encoding. * * @param path The path to the file whose contents the OFINIFile should contain * @param encoding The encoding of the specified file * * @return A new, autoreleased OFINIFile with the contents of the specified file */ + (instancetype)fileWithPath: (OFString *)path | > > > > > | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | */ OF_SUBCLASSING_RESTRICTED @interface OFINIFile: OFObject { OFMutableArray OF_GENERIC(OFINICategory *) *_categories; } /** * @brief All categories in the INI file. */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFINICategory *) *categories; /** * @brief Creates a new OFINIFile with the contents of the specified file. * * @param path The path to the file whose contents the OFINIFile should contain * * @return A new, autoreleased OFINIFile with the contents of the specified file */ + (instancetype)fileWithPath: (OFString *)path; /** * @brief Creates a new OFINIFile with the contents of the specified file in * the specified encoding. * * @param path The path to the file whose contents the OFINIFile should contain * @param encoding The encoding of the specified file * * @return A new, autoreleased OFINIFile with the contents of the specified file */ + (instancetype)fileWithPath: (OFString *)path encoding: (OFStringEncoding)encoding; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFINIFile with the contents of the * specified file. * |
︙ | ︙ | |||
73 74 75 76 77 78 79 | * * @param path The path to the file whose contents the OFINIFile should contain * @param encoding The encoding of the specified file * * @return An initialized OFINIFile with the contents of the specified file */ - (instancetype)initWithPath: (OFString *)path | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | * * @param path The path to the file whose contents the OFINIFile should contain * @param encoding The encoding of the specified file * * @return An initialized OFINIFile with the contents of the specified file */ - (instancetype)initWithPath: (OFString *)path encoding: (OFStringEncoding)encoding OF_DESIGNATED_INITIALIZER; /** * @brief Returns an @ref OFINICategory for the category with the specified * name. * * @param name The name of the category for which an @ref OFINICategory should |
︙ | ︙ | |||
101 102 103 104 105 106 107 | /** * @brief Writes the contents of the OFINIFile to a file in the specified * encoding. * * @param path The path of the file to write to * @param encoding The encoding to use */ | | < | 104 105 106 107 108 109 110 111 112 113 114 | /** * @brief Writes the contents of the OFINIFile to a file in the specified * encoding. * * @param path The path of the file to write to * @param encoding The encoding to use */ - (void)writeToFile: (OFString *)path encoding: (OFStringEncoding)encoding; @end OF_ASSUME_NONNULL_END |
Modified src/OFINIFile.m from [e386265069] to [f3dcfaef7e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | #import "OFINICategory+Private.h" #import "OFInvalidFormatException.h" #import "OFOpenItemFailedException.h" OF_DIRECT_MEMBERS @interface OFINIFile () | | < | > > | | < | | < | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | #import "OFINICategory+Private.h" #import "OFInvalidFormatException.h" #import "OFOpenItemFailedException.h" OF_DIRECT_MEMBERS @interface OFINIFile () - (void)of_parseFile: (OFString *)path encoding: (OFStringEncoding)encoding; @end static bool isWhitespaceLine(OFString *line) { const char *cString = line.UTF8String; size_t length = line.UTF8StringLength; for (size_t i = 0; i < length; i++) if (!OFASCIIIsSpace(cString[i])) return false; return true; } @implementation OFINIFile @synthesize categories = _categories; + (instancetype)fileWithPath: (OFString *)path { return [[[self alloc] initWithPath: path] autorelease]; } + (instancetype)fileWithPath: (OFString *)path encoding: (OFStringEncoding)encoding { return [[[self alloc] initWithPath: path encoding: encoding] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithPath: (OFString *)path { return [self initWithPath: path encoding: OFStringEncodingUTF8]; } - (instancetype)initWithPath: (OFString *)path encoding: (OFStringEncoding)encoding { self = [super init]; @try { _categories = [[OFMutableArray alloc] init]; [self of_parseFile: path encoding: encoding]; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
110 111 112 113 114 115 116 | [_categories addObject: category]; objc_autoreleasePoolPop(pool); return category; } | | < | < | < | < | < | < > > > > > > | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | [_categories addObject: category]; objc_autoreleasePoolPop(pool); return category; } - (void)of_parseFile: (OFString *)path encoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); OFFile *file; OFINICategory *category = nil; OFString *line; @try { file = [OFFile fileWithPath: path mode: @"r"]; } @catch (OFOpenItemFailedException *e) { /* Handle missing file like an empty file */ if (e.errNo == ENOENT) return; @throw e; } while ((line = [file readLineWithEncoding: encoding]) != nil) { if (isWhitespaceLine(line)) continue; if ([line hasPrefix: @"["]) { OFString *categoryName; if (![line hasSuffix: @"]"]) @throw [OFInvalidFormatException exception]; categoryName = [line substringWithRange: OFRangeMake(1, line.length - 2)]; category = [[[OFINICategory alloc] of_initWithName: categoryName] autorelease]; [_categories addObject: category]; } else { if (category == nil) @throw [OFInvalidFormatException exception]; [category of_parseLine: line]; } } objc_autoreleasePoolPop(pool); } - (void)writeToFile: (OFString *)path { [self writeToFile: path encoding: OFStringEncodingUTF8]; } - (void)writeToFile: (OFString *)path encoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); OFFile *file = [OFFile fileWithPath: path mode: @"w"]; bool first = true; for (OFINICategory *category in _categories) if ([category of_writeToStream: file encoding: encoding first: first]) first = false; objc_autoreleasePoolPop(pool); } - (OFString *)description { return [OFString stringWithFormat: @"<%@: %@>", self.class, _categories]; } @end |
Modified src/OFINIFileSettings.h from [23812347d2] to [1f5bf8dc61].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFINIFileSettings.m from [062d94ddbb] to [768ab5ebfe].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
55 56 57 58 59 60 61 | } - (void)of_getCategory: (OFString **)category andKey: (OFString **)key forPath: (OFString *)path OF_DIRECT { size_t pos = [path rangeOfString: @"." | | | | < | > | > > | > | > > > > | | < | | < < < | < < | | > | > > | > | > > > > | < | | | < < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < | | | < < < | | | < | < < < | < | < < < | < | < < < | | < < < | | < < < | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | } - (void)of_getCategory: (OFString **)category andKey: (OFString **)key forPath: (OFString *)path OF_DIRECT { size_t pos = [path rangeOfString: @"." options: OFStringSearchBackwards].location; if (pos == OFNotFound) { *category = @""; *key = path; return; } *category = [path substringToIndex: pos]; *key = [path substringFromIndex: pos + 1]; } - (void)setString: (OFString *)string forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setString: string forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setLongLong: (long long)longLong forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setLongLong: longLong forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setBool: (bool)bool_ forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setBool: bool_ forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setFloat: (float)float_ forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setFloat: float_ forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setDouble: (double)double_ forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setDouble: double_ forKey: key]; objc_autoreleasePoolPop(pool); } - (void)setStringArray: (OFArray OF_GENERIC(OFString *) *)array forPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] setStringArray: array forKey: key]; objc_autoreleasePoolPop(pool); } - (OFString *)stringForPath: (OFString *)path defaultValue: (OFString *)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *category, *key, *ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] stringForKey: key defaultValue: defaultValue]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (long long)longLongForPath: (OFString *)path defaultValue: (long long)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; long long ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] longLongForKey: key defaultValue: defaultValue]; objc_autoreleasePoolPop(pool); return ret; } - (bool)boolForPath: (OFString *)path defaultValue: (bool)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; bool ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] boolForKey: key defaultValue: defaultValue]; objc_autoreleasePoolPop(pool); return ret; } - (float)floatForPath: (OFString *)path defaultValue: (float)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; float ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] floatForKey: key defaultValue: defaultValue]; objc_autoreleasePoolPop(pool); return ret; } - (double)doubleForPath: (OFString *)path defaultValue: (double)defaultValue { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; double ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] doubleForKey: key defaultValue: defaultValue]; objc_autoreleasePoolPop(pool); return ret; } - (OFArray OF_GENERIC(OFString *) *)stringArrayForPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; OFArray *ret; [self of_getCategory: &category andKey: &key forPath: path]; ret = [[_INIFile categoryForName: category] stringArrayForKey: key]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (void)removeValueForPath: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFString *category, *key; [self of_getCategory: &category andKey: &key forPath: path]; [[_INIFile categoryForName: category] removeValueForKey: key]; objc_autoreleasePoolPop(pool); } - (void)save { [_INIFile writeToFile: _filePath]; } @end |
Modified src/OFIPSocketAsyncConnector.h from [36d029e68c] to [248ffd2ce4].
1 | /* | < < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFDNSResolver.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" OF_ASSUME_NONNULL_BEGIN @protocol OFIPSocketAsyncConnecting - (bool)of_createSocketForAddress: (const OFSocketAddress *)address errNo: (int *)errNo; - (bool)of_connectSocketToAddress: (const OFSocketAddress *)address errNo: (int *)errNo; - (void)of_closeSocket; @end @interface OFIPSocketAsyncConnector: OFObject <OFRunLoopConnectDelegate, OFDNSResolverHostDelegate> { |
︙ | ︙ | |||
44 45 46 47 48 49 50 | - (instancetype)initWithSocket: (id)sock host: (OFString *)host port: (uint16_t)port delegate: (nullable id)delegate block: (nullable id)block; - (void)didConnect; | | | | 42 43 44 45 46 47 48 49 50 51 52 53 | - (instancetype)initWithSocket: (id)sock host: (OFString *)host port: (uint16_t)port delegate: (nullable id)delegate block: (nullable id)block; - (void)didConnect; - (void)tryNextAddressWithRunLoopMode: (OFRunLoopMode)runLoopMode; - (void)startWithRunLoopMode: (OFRunLoopMode)runLoopMode; @end OF_ASSUME_NONNULL_END |
Modified src/OFIPSocketAsyncConnector.m from [6a448fb9d2] to [e235fd33e4].
1 | /* | < < | < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFIPSocketAsyncConnector.h" #import "OFData.h" #import "OFTCPSocket.h" #import "OFThread.h" #import "OFTimer.h" #import "OFConnectionFailedException.h" #import "OFInvalidFormatException.h" |
︙ | ︙ | |||
70 71 72 73 74 75 76 | { if (_exception == nil) [_socket setCanBlock: true]; #ifdef OF_HAVE_BLOCKS if (_block != NULL) { if ([_socket isKindOfClass: [OFTCPSocket class]]) | < | < < < < < | | < | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | { if (_exception == nil) [_socket setCanBlock: true]; #ifdef OF_HAVE_BLOCKS if (_block != NULL) { if ([_socket isKindOfClass: [OFTCPSocket class]]) ((OFTCPSocketAsyncConnectBlock)_block)(_exception); else OFEnsure(0); } else { #endif if ([_delegate respondsToSelector: @selector(socket:didConnectToHost:port:exception:)]) [_delegate socket: _socket didConnectToHost: _host port: _port exception: _exception]; #ifdef OF_HAVE_BLOCKS } #endif } - (void)of_socketDidConnect: (id)sock exception: (id)exception { if (exception != nil) { /* * self might be retained only by the pending async requests, * which we're about to cancel. */ [[self retain] autorelease]; |
︙ | ︙ | |||
123 124 125 126 127 128 129 | @selector(tryNextAddressWithRunLoopMode:); OFTimer *timer = [OFTimer timerWithTimeInterval: 0 target: self selector: selector object: runLoop.currentMode repeats: false]; | | < | | | | < | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | @selector(tryNextAddressWithRunLoopMode:); OFTimer *timer = [OFTimer timerWithTimeInterval: 0 target: self selector: selector object: runLoop.currentMode repeats: false]; [runLoop addTimer: timer forMode: runLoop.currentMode]; } return; } [self didConnect]; } - (id)of_connectionFailedExceptionForErrNo: (int)errNo { return [OFConnectionFailedException exceptionWithHost: _host port: _port socket: _socket errNo: errNo]; } - (void)tryNextAddressWithRunLoopMode: (OFRunLoopMode)runLoopMode { OFSocketAddress address = *(const OFSocketAddress *) [_socketAddresses itemAtIndex: _socketAddressesIndex++]; int errNo; OFSocketAddressSetPort(&address, _port); if (![_socket of_createSocketForAddress: &address errNo: &errNo]) { if (_socketAddressesIndex >= _socketAddresses.count) { _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: _socket errNo: errNo]; [self didConnect]; |
︙ | ︙ | |||
181 182 183 184 185 186 187 | * FIXME: Use a different thread as a work around. */ [_socket setCanBlock: true]; #else [_socket setCanBlock: false]; #endif | | < > > > > | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | * FIXME: Use a different thread as a work around. */ [_socket setCanBlock: true]; #else [_socket setCanBlock: false]; #endif if (![_socket of_connectSocketToAddress: &address errNo: &errNo]) { #if !defined(OF_NINTENDO_3DS) && !defined(OF_WII) # ifdef OF_WINDOWS if (errNo == EINPROGRESS || errNo == EWOULDBLOCK) { # else if (errNo == EINPROGRESS) { # endif [OFRunLoop of_addAsyncConnectForSocket: _socket mode: runLoopMode delegate: self]; return; } else { #endif [_socket of_closeSocket]; |
︙ | ︙ | |||
234 235 236 237 238 239 240 | _socketAddresses = [addresses copy]; [self tryNextAddressWithRunLoopMode: [OFRunLoop currentRunLoop].currentMode]; } | | < | > | < | | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | _socketAddresses = [addresses copy]; [self tryNextAddressWithRunLoopMode: [OFRunLoop currentRunLoop].currentMode]; } - (void)startWithRunLoopMode: (OFRunLoopMode)runLoopMode { @try { OFSocketAddress address = OFSocketAddressParseIP(_host, _port); _socketAddresses = [[OFData alloc] initWithItems: &address count: 1 itemSize: sizeof(address)]; [self tryNextAddressWithRunLoopMode: runLoopMode]; return; } @catch (OFInvalidFormatException *e) { } [[OFThread DNSResolver] asyncResolveAddressesForHost: _host addressFamily: OFSocketAddressFamilyAny runLoopMode: runLoopMode delegate: self]; } @end |
Modified src/OFIPXSocket.h from [fb0c56ae44] to [a2ca3d4d82].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | @end /** * @class OFIPXSocket OFIPXSocket.h ObjFW/OFIPXSocket.h * * @brief A class which provides methods to create and use IPX sockets. * | | | | | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | @end /** * @class OFIPXSocket OFIPXSocket.h ObjFW/OFIPXSocket.h * * @brief A class which provides methods to create and use IPX sockets. * * Addresses are of type @ref OFSocketAddress. You can use * @ref OFSocketAddressMakeIPX to create an address or * @ref OFSocketAddressIPXNetwork to get the IPX network, * @ref OFSocketAddressIPXNode to get the IPX node and * @ref OFSocketAddressPort to get the port (sometimes also called * socket number). * * @warning Even though the OFCopying protocol is implemented, it does *not* * return an independent copy of the socket, but instead retains it. * This is so that the socket can be used as a key for a dictionary, * so context can be associated with a socket. Using a socket in more * than one thread at the same time is not thread-safe, even if copy |
︙ | ︙ | |||
70 71 72 73 74 75 76 | * specified packet type. * * @param port The port (sometimes called socket number) to bind to. 0 means to * pick one and return it. * @param packetType The packet type to use on the socket * @return The address on which this socket can be reached */ | < | | 68 69 70 71 72 73 74 75 76 77 78 | * specified packet type. * * @param port The port (sometimes called socket number) to bind to. 0 means to * pick one and return it. * @param packetType The packet type to use on the socket * @return The address on which this socket can be reached */ - (OFSocketAddress)bindToPort: (uint16_t)port packetType: (uint8_t)packetType; @end OF_ASSUME_NONNULL_END |
Modified src/OFIPXSocket.m from [06e0564b9c] to [832ec6a7bd].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 | #include <errno.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFIPXSocket.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" | > > < < < < | | | | | | | | | | | | | | | | | < < | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | #include <errno.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFIPXSocket.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" @implementation OFIPXSocket @dynamic delegate; - (OFSocketAddress)bindToPort: (uint16_t)port packetType: (uint8_t)packetType { const unsigned char zeroNode[IPX_NODE_LEN] = { 0 }; OFSocketAddress address; int protocol = 0; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; address = OFSocketAddressMakeIPX(zeroNode, 0, port); #ifdef OF_WINDOWS protocol = NSPROTO_IPX + packetType; #else _packetType = address.sockaddr.ipx.sipx_type = packetType; #endif if ((_socket = socket(address.sockaddr.sockaddr.sa_family, SOCK_DGRAM | SOCK_CLOEXEC, protocol)) == OFInvalidSocketHandle) @throw [OFBindFailedException exceptionWithPort: port packetType: packetType socket: self errNo: OFSocketErrNo()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithPort: port packetType: packetType socket: self errNo: errNo]; } memset(&address, 0, sizeof(address)); address.family = OFSocketAddressFamilyIPX; address.length = (socklen_t)sizeof(address.sockaddr); if (OFGetSockName(_socket, &address.sockaddr.sockaddr, &address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithPort: port packetType: packetType socket: self errNo: errNo]; } if (address.sockaddr.sockaddr.sa_family != AF_IPX) { closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithPort: port packetType: packetType socket: self errNo: EAFNOSUPPORT]; } return address; } #ifndef OF_WINDOWS - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const OFSocketAddress *)receiver { OFSocketAddress fixedReceiver; memcpy(&fixedReceiver, receiver, sizeof(fixedReceiver)); /* If it's not IPX, no fix-up needed - it will fail anyway. */ if (fixedReceiver.family == OFSocketAddressFamilyIPX) fixedReceiver.sockaddr.ipx.sipx_type = _packetType; [super sendBuffer: buffer length: length receiver: &fixedReceiver]; } #endif @end |
Modified src/OFInflate64Stream.h from [701031a024] to [2f3dc057f8].
1 | /* | < < | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFStream.h" #import "OFKernelEventObserver.h" OF_ASSUME_NONNULL_BEGIN #define OFInflate64StreamBufferSize 4096 /** * @class OFInflate64Stream OFInflate64Stream.h ObjFW/OFInflate64Stream.h * * @note This class only conforms to OFReadyForReadingObserving if the * underlying stream does so, too. * * @brief A class that handles Deflate decompression transparently for an * underlying stream. */ OF_SUBCLASSING_RESTRICTED @interface OFInflate64Stream: OFStream <OFReadyForReadingObserving> { OFStream *_stream; unsigned char _buffer[OFInflate64StreamBufferSize]; uint16_t _bufferIndex, _bufferLength; uint8_t _byte; uint8_t _bitIndex, _savedBitsLength; uint16_t _savedBits; unsigned char *_Nullable _slidingWindow; uint16_t _slidingWindowIndex, _slidingWindowMask; int _state; union { struct { uint8_t position; uint8_t length[4]; } uncompressedHeader; struct { uint16_t position, length; } uncompressed; struct { struct _OFHuffmanTree *_Nullable litLenTree; struct _OFHuffmanTree *_Nullable distTree; struct _OFHuffmanTree *_Nullable codeLenTree; struct _OFHuffmanTree *_Nullable treeIter; uint8_t *_Nullable lengths; uint16_t receivedCount; uint8_t value, litLenCodesCount, distCodesCount; uint8_t codeLenCodesCount; } huffmanTree; struct { struct _OFHuffmanTree *_Nullable litLenTree; struct _OFHuffmanTree *_Nullable distTree; struct _OFHuffmanTree *_Nullable treeIter; int state; uint16_t value, length, distance, extraBits; } huffman; } _context; bool _inLastBlock, _atEndOfStream; } |
︙ | ︙ |
Modified src/OFInflate64Stream.m from [01fc1ef62b] to [96e65e9055].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFInflateStream.h from [c18a2de259] to [fe62e030fd].
1 | /* | < < | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFStream.h" #import "OFKernelEventObserver.h" OF_ASSUME_NONNULL_BEGIN #define OFInflateStreamBufferSize 4096 /** * @class OFInflateStream OFInflateStream.h ObjFW/OFInflateStream.h * * @note This class only conforms to OFReadyForReadingObserving if the * underlying stream does so, too. * * @brief A class that handles Deflate decompression transparently for an * underlying stream. */ OF_SUBCLASSING_RESTRICTED @interface OFInflateStream: OFStream <OFReadyForReadingObserving> { OFStream *_stream; unsigned char _buffer[OFInflateStreamBufferSize]; uint16_t _bufferIndex, _bufferLength; uint8_t _byte; uint8_t _bitIndex, _savedBitsLength; uint16_t _savedBits; unsigned char *_Nullable _slidingWindow; uint16_t _slidingWindowIndex, _slidingWindowMask; int _state; union { struct { uint8_t position; uint8_t length[4]; } uncompressedHeader; struct { uint16_t position, length; } uncompressed; struct { struct _OFHuffmanTree *_Nullable litLenTree; struct _OFHuffmanTree *_Nullable distTree; struct _OFHuffmanTree *_Nullable codeLenTree; struct _OFHuffmanTree *_Nullable treeIter; uint8_t *_Nullable lengths; uint16_t receivedCount; uint8_t value, litLenCodesCount, distCodesCount; uint8_t codeLenCodesCount; } huffmanTree; struct { struct _OFHuffmanTree *_Nullable litLenTree; struct _OFHuffmanTree *_Nullable distTree; struct _OFHuffmanTree *_Nullable treeIter; int state; uint16_t value, length, distance, extraBits; } huffman; } _context; bool _inLastBlock, _atEndOfStream; } |
︙ | ︙ |
Modified src/OFInflateStream.m from [c1d8d6e047] to [28d4702177].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | #ifndef OF_INFLATE64_STREAM_M # import "OFInflateStream.h" #else # import "OFInflate64Stream.h" # define OFInflateStream OFInflate64Stream #endif | < | | | | | | | | | > | < | | | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #ifndef OF_INFLATE64_STREAM_M # import "OFInflateStream.h" #else # import "OFInflate64Stream.h" # define OFInflateStream OFInflate64Stream #endif #import "OFHuffmanTree.h" #import "OFInitializationFailedException.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" #import "OFOutOfMemoryException.h" #ifndef OF_INFLATE64_STREAM_M # define bufferSize OFInflateStreamBufferSize #else # define bufferSize OFInflate64StreamBufferSize #endif enum State { stateBlockHeader, stateUncompressedBlockHeader, stateUncompressedBlock, stateHuffmanTree, stateHuffmanBlock }; enum HuffmanState { huffmanStateWriteValue, huffmanStateAwaitCode, huffmanStateAwaitLengthExtraBits, huffmanStateAwaitDistance, huffmanStateAwaitDistanceExtraBits, huffmanStateProcessPair }; #ifndef OF_INFLATE64_STREAM_M static const uint8_t numDistanceCodes = 30; static const uint8_t lengthCodes[29] = { /* indices are -257, values -3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, |
︙ | ︙ | |||
98 99 100 101 102 103 104 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14 }; #endif static const uint8_t codeLengthsOrder[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; | | | | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14 }; #endif static const uint8_t codeLengthsOrder[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; static OFHuffmanTree fixedLitLenTree, fixedDistTree; @implementation OFInflateStream static OF_INLINE bool tryReadBits(OFInflateStream *stream, uint16_t *bits, uint8_t count) { uint16_t ret = stream->_savedBits; assert(stream->_savedBitsLength < count); for (uint_fast8_t i = stream->_savedBitsLength; i < count; i++) { if OF_UNLIKELY (stream->_bitIndex == 8) { if OF_LIKELY (stream->_bufferIndex < stream->_bufferLength) stream->_byte = stream->_buffer[stream->_bufferIndex++]; else { size_t length = [stream->_stream readIntoBuffer: stream->_buffer length: bufferSize]; if OF_UNLIKELY (length < 1) { stream->_savedBits = ret; stream->_savedBitsLength = i; return false; } |
︙ | ︙ | |||
159 160 161 162 163 164 165 | for (uint16_t i = 144; i <= 255; i++) lengths[i] = 9; for (uint16_t i = 256; i <= 279; i++) lengths[i] = 7; for (uint16_t i = 280; i <= 287; i++) lengths[i] = 8; | | | | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | for (uint16_t i = 144; i <= 255; i++) lengths[i] = 9; for (uint16_t i = 256; i <= 279; i++) lengths[i] = 7; for (uint16_t i = 280; i <= 287; i++) lengths[i] = 8; fixedLitLenTree = OFHuffmanTreeNew(lengths, 288); for (uint16_t i = 0; i <= 31; i++) lengths[i] = 5; fixedDistTree = OFHuffmanTreeNew(lengths, 32); } + (instancetype)streamWithStream: (OFStream *)stream { return [[[self alloc] initWithStream: stream] autorelease]; } |
︙ | ︙ | |||
192 193 194 195 196 197 198 | _bitIndex = 8; #ifdef OF_INFLATE64_STREAM_M _slidingWindowMask = 0xFFFF; #else _slidingWindowMask = 0x7FFF; #endif | < | > > | > > < | | | > | | | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | _bitIndex = 8; #ifdef OF_INFLATE64_STREAM_M _slidingWindowMask = 0xFFFF; #else _slidingWindowMask = 0x7FFF; #endif _slidingWindow = OFAllocZeroedMemory(_slidingWindowMask + 1, 1); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_stream != nil) [self close]; OFFreeMemory(_slidingWindow); if (_state == stateHuffmanTree) { OFFreeMemory(_context.huffmanTree.lengths); if (_context.huffmanTree.codeLenTree != NULL) OFHuffmanTreeFree(_context.huffmanTree.codeLenTree); } if (_state == stateHuffmanTree || _state == stateHuffmanBlock) { if (_context.huffman.litLenTree != fixedLitLenTree) OFHuffmanTreeFree(_context.huffman.litLenTree); if (_context.huffman.distTree != fixedDistTree) OFHuffmanTreeFree(_context.huffman.distTree); } [super dealloc]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer_ length: (size_t)length |
︙ | ︙ | |||
238 239 240 241 242 243 244 | if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) return 0; start: | | | | | | | | | | | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) return 0; start: switch ((enum State)_state) { case stateBlockHeader: if OF_UNLIKELY (_inLastBlock) { [_stream unreadFromBuffer: _buffer + _bufferIndex length: _bufferLength - _bufferIndex]; _bufferIndex = _bufferLength = 0; _atEndOfStream = true; return bytesWritten; } if OF_UNLIKELY (!tryReadBits(self, &bits, 3)) return bytesWritten; _inLastBlock = (bits & 1); switch (bits >> 1) { case 0: /* No compression */ _state = stateUncompressedBlockHeader; _bitIndex = 8; _context.uncompressedHeader.position = 0; memset(_context.uncompressedHeader.length, 0, 4); break; case 1: /* Fixed Huffman */ _state = stateHuffmanBlock; _context.huffman.state = huffmanStateAwaitCode; _context.huffman.litLenTree = fixedLitLenTree; _context.huffman.distTree = fixedDistTree; _context.huffman.treeIter = fixedLitLenTree; break; case 2: /* Dynamic Huffman */ _state = stateHuffmanTree; _context.huffmanTree.lengths = NULL; _context.huffmanTree.receivedCount = 0; _context.huffmanTree.value = 0xFE; _context.huffmanTree.litLenCodesCount = 0xFF; _context.huffmanTree.distCodesCount = 0xFF; _context.huffmanTree.codeLenCodesCount = 0xFF; break; default: @throw [OFInvalidFormatException exception]; } goto start; case stateUncompressedBlockHeader: #define CTX _context.uncompressedHeader /* FIXME: This can be done more efficiently than unreading */ [_stream unreadFromBuffer: _buffer + _bufferIndex length: _bufferLength - _bufferIndex]; _bufferIndex = _bufferLength = 0; CTX.position += [_stream readIntoBuffer: CTX.length + CTX.position length: 4 - CTX.position]; if OF_UNLIKELY (CTX.position < 4) return bytesWritten; if OF_UNLIKELY ((CTX.length[0] | (CTX.length[1] << 8)) != (uint16_t)~(CTX.length[2] | (CTX.length[3] << 8))) @throw [OFInvalidFormatException exception]; _state = stateUncompressedBlock; /* * Do not reorder! _context.uncompressed.position and * _context.uncompressedHeader.length overlap! */ _context.uncompressed.length = CTX.length[0] | (CTX.length[1] << 8); _context.uncompressed.position = 0; goto start; #undef CTX case stateUncompressedBlock: #define CTX _context.uncompressed if OF_UNLIKELY (length == 0) return bytesWritten; tmp = (length < (size_t)CTX.length - CTX.position ? (uint16_t)length : CTX.length - CTX.position); |
︙ | ︙ | |||
339 340 341 342 343 344 345 | _slidingWindowIndex = slidingWindowIndex; length -= tmp; bytesWritten += tmp; CTX.position += tmp; if OF_UNLIKELY (CTX.position == CTX.length) | | | | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 | _slidingWindowIndex = slidingWindowIndex; length -= tmp; bytesWritten += tmp; CTX.position += tmp; if OF_UNLIKELY (CTX.position == CTX.length) _state = stateBlockHeader; goto start; #undef CTX case stateHuffmanTree: #define CTX _context.huffmanTree if OF_LIKELY (CTX.value == 0xFE) { if OF_LIKELY (CTX.litLenCodesCount == 0xFF) { if OF_UNLIKELY (!tryReadBits(self, &bits, 5)) return bytesWritten; if OF_UNLIKELY (bits > 29) |
︙ | ︙ | |||
372 373 374 375 376 377 378 | if OF_UNLIKELY (!tryReadBits(self, &bits, 4)) return bytesWritten; CTX.codeLenCodesCount = bits; } if OF_LIKELY (CTX.lengths == NULL) | | < < | | | | | | 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | if OF_UNLIKELY (!tryReadBits(self, &bits, 4)) return bytesWritten; CTX.codeLenCodesCount = bits; } if OF_LIKELY (CTX.lengths == NULL) CTX.lengths = OFAllocZeroedMemory(19, 1); for (uint16_t i = CTX.receivedCount; i < CTX.codeLenCodesCount + 4; i++) { if OF_UNLIKELY (!tryReadBits(self, &bits, 3)) { CTX.receivedCount = i; return bytesWritten; } CTX.lengths[codeLengthsOrder[i]] = bits; } CTX.codeLenTree = OFHuffmanTreeNew(CTX.lengths, 19); CTX.treeIter = CTX.codeLenTree; OFFreeMemory(CTX.lengths); CTX.lengths = NULL; CTX.receivedCount = 0; CTX.value = 0xFF; } if OF_LIKELY (CTX.lengths == NULL) CTX.lengths = OFAllocMemory( CTX.litLenCodesCount + CTX.distCodesCount + 258, 1); for (uint16_t i = CTX.receivedCount; i < CTX.litLenCodesCount + CTX.distCodesCount + 258;) { uint8_t j, count; if OF_LIKELY (CTX.value == 0xFF) { if OF_UNLIKELY (!OFHuffmanTreeWalk(self, tryReadBits, &CTX.treeIter, &value)) { CTX.receivedCount = i; return bytesWritten; } CTX.treeIter = CTX.codeLenTree; |
︙ | ︙ | |||
471 472 473 474 475 476 477 | for (j = 0; j < count; j++) CTX.lengths[i++] = value; CTX.value = 0xFF; } | | | | | | | | | | | > | | | > | < > | | > | | | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 | for (j = 0; j < count; j++) CTX.lengths[i++] = value; CTX.value = 0xFF; } OFHuffmanTreeFree(CTX.codeLenTree); CTX.codeLenTree = NULL; CTX.litLenTree = OFHuffmanTreeNew(CTX.lengths, CTX.litLenCodesCount + 257); CTX.distTree = OFHuffmanTreeNew( CTX.lengths + CTX.litLenCodesCount + 257, CTX.distCodesCount + 1); OFFreeMemory(CTX.lengths); /* * litLenTree and distTree are at the same location in * _context.huffman and _context.huffmanTree, thus no need to * set them. */ _state = stateHuffmanBlock; _context.huffman.state = huffmanStateAwaitCode; _context.huffman.treeIter = CTX.litLenTree; goto start; #undef CTX case stateHuffmanBlock: #define CTX _context.huffman for (;;) { uint8_t extraBits, lengthCodeIndex; if OF_UNLIKELY (CTX.state == huffmanStateWriteValue) { if OF_UNLIKELY (length == 0) return bytesWritten; buffer[bytesWritten++] = CTX.value; length--; _slidingWindow[_slidingWindowIndex] = CTX.value; _slidingWindowIndex = (_slidingWindowIndex + 1) & _slidingWindowMask; CTX.state = huffmanStateAwaitCode; CTX.treeIter = CTX.litLenTree; } if OF_UNLIKELY (CTX.state == huffmanStateAwaitLengthExtraBits) { if OF_UNLIKELY (!tryReadBits(self, &bits, CTX.extraBits)) return bytesWritten; CTX.length += bits; CTX.state = huffmanStateAwaitDistance; CTX.treeIter = CTX.distTree; } /* Distance of length distance pair */ if (CTX.state == huffmanStateAwaitDistance) { if OF_UNLIKELY (!OFHuffmanTreeWalk(self, tryReadBits, &CTX.treeIter, &value)) return bytesWritten; if OF_UNLIKELY (value >= numDistanceCodes) @throw [OFInvalidFormatException exception]; CTX.distance = distanceCodes[value]; extraBits = distanceExtraBits[value]; if (extraBits > 0) { if OF_UNLIKELY (!tryReadBits(self, &bits, extraBits)) { #define HSADEB huffmanStateAwaitDistanceExtraBits CTX.state = HSADEB; #undef HSADEB CTX.extraBits = extraBits; return bytesWritten; } CTX.distance += bits; } CTX.state = huffmanStateProcessPair; } else if (CTX.state == huffmanStateAwaitDistanceExtraBits) { if OF_UNLIKELY (!tryReadBits(self, &bits, CTX.extraBits)) return bytesWritten; CTX.distance += bits; CTX.state = huffmanStateProcessPair; } /* Length distance pair */ if (CTX.state == huffmanStateProcessPair) { for (uint_fast16_t j = 0; j < CTX.length; j++) { uint16_t idx; if OF_UNLIKELY (length == 0) { CTX.length -= j; return bytesWritten; } |
︙ | ︙ | |||
585 586 587 588 589 590 591 | _slidingWindow[_slidingWindowIndex] = value; _slidingWindowIndex = (_slidingWindowIndex + 1) & _slidingWindowMask; } | | | | | | | | 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 | _slidingWindow[_slidingWindowIndex] = value; _slidingWindowIndex = (_slidingWindowIndex + 1) & _slidingWindowMask; } CTX.state = huffmanStateAwaitCode; CTX.treeIter = CTX.litLenTree; } if OF_UNLIKELY (!OFHuffmanTreeWalk(self, tryReadBits, &CTX.treeIter, &value)) return bytesWritten; /* End of block */ if OF_UNLIKELY (value == 256) { if (CTX.litLenTree != fixedLitLenTree) OFHuffmanTreeFree(CTX.litLenTree); if (CTX.distTree != fixedDistTree) OFHuffmanTreeFree(CTX.distTree); _state = stateBlockHeader; goto start; } /* Literal byte */ if OF_LIKELY (value < 256) { if OF_UNLIKELY (length == 0) { CTX.state = huffmanStateWriteValue; CTX.value = value; return bytesWritten; } buffer[bytesWritten++] = value; length--; |
︙ | ︙ | |||
636 637 638 639 640 641 642 | CTX.length = lengthCodes[lengthCodeIndex] + 3; extraBits = lengthExtraBits[lengthCodeIndex]; if (extraBits > 0) { if OF_UNLIKELY (!tryReadBits(self, &bits, extraBits)) { CTX.extraBits = extraBits; | | > | | 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 | CTX.length = lengthCodes[lengthCodeIndex] + 3; extraBits = lengthExtraBits[lengthCodeIndex]; if (extraBits > 0) { if OF_UNLIKELY (!tryReadBits(self, &bits, extraBits)) { CTX.extraBits = extraBits; CTX.state = huffmanStateAwaitLengthExtraBits; return bytesWritten; } CTX.length += bits; } CTX.treeIter = CTX.distTree; CTX.state = huffmanStateAwaitDistance; } break; #undef CTX } OF_UNREACHABLE |
︙ | ︙ |
Modified src/OFInvertedCharacterSet.h from [08af99fb50] to [d4b8559d77].
1 | /* | < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFCharacterSet.h" OF_ASSUME_NONNULL_BEGIN @interface OFInvertedCharacterSet: OFCharacterSet { OFCharacterSet *_characterSet; bool (*_characterIsMember)(id, SEL, OFUnichar); } - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet; @end OF_ASSUME_NONNULL_END |
Modified src/OFInvertedCharacterSet.m from [33cd491c87] to [1e78ebb0a4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet { self = [super init]; @try { _characterSet = [characterSet retain]; | | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet { self = [super init]; @try { _characterSet = [characterSet retain]; _characterIsMember = (bool (*)(id, SEL, OFUnichar)) [_characterSet methodForSelector: @selector(characterIsMember:)]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_characterSet release]; [super dealloc]; } - (bool)characterIsMember: (OFUnichar)character { return !_characterIsMember(_characterSet, @selector(characterIsMember:), character); } - (OFCharacterSet *)invertedSet { return [[_characterSet retain] autorelease]; } @end |
Modified src/OFInvocation.h from [86507cef33] to [324ba0dca4].
1 | /* | < < | < < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN @class OFMethodSignature; @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableData; /** * @class OFInvocation OFInvocation.h ObjFW/OFInvocation.h * |
︙ | ︙ | |||
72 73 74 75 76 77 78 | /** * @brief Sets the argument for the specified index. * * @param buffer The buffer in which the argument is stored * @param index The index of the argument to set */ | | < | < < < < < < < < | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | /** * @brief Sets the argument for the specified index. * * @param buffer The buffer in which the argument is stored * @param index The index of the argument to set */ - (void)setArgument: (const void *)buffer atIndex: (size_t)index; /** * @brief Gets the argument for the specified index. * * @param buffer The buffer in which the argument is stored * @param index The index of the argument to get */ - (void)getArgument: (void *)buffer atIndex: (size_t)index; /** * @brief Sets the return value. * * @param buffer The buffer in which the return value is stored */ - (void)setReturnValue: (const void *)buffer; /** * @brief Gets the return value. * * @param buffer The buffer in which the return value is stored */ - (void)getReturnValue: (void *)buffer; @end OF_ASSUME_NONNULL_END |
Modified src/OFInvocation.m from [f9deea1e14] to [5937b080ad].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #include <string.h> #import "OFInvocation.h" #import "OFArray.h" #import "OFData.h" #import "OFMethodSignature.h" | < < < < | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include <string.h> #import "OFInvocation.h" #import "OFArray.h" #import "OFData.h" #import "OFMethodSignature.h" @implementation OFInvocation @synthesize methodSignature = _methodSignature; + (instancetype)invocationWithMethodSignature: (OFMethodSignature *)signature { return [[[self alloc] initWithMethodSignature: signature] autorelease]; } |
︙ | ︙ | |||
50 51 52 53 54 55 56 | _arguments = [[OFMutableArray alloc] init]; for (size_t i = 0; i < numberOfArguments; i++) { OFMutableData *data; typeEncoding = [_methodSignature argumentTypeAtIndex: i]; | | | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | _arguments = [[OFMutableArray alloc] init]; for (size_t i = 0; i < numberOfArguments; i++) { OFMutableData *data; typeEncoding = [_methodSignature argumentTypeAtIndex: i]; typeSize = OFSizeOfTypeEncoding(typeEncoding); data = [OFMutableData dataWithItemSize: typeSize capacity: 1]; [data increaseCountBy: 1]; [_arguments addObject: data]; } typeEncoding = _methodSignature.methodReturnType; typeSize = OFSizeOfTypeEncoding(typeEncoding); if (typeSize > 0) { _returnValue = [[OFMutableData alloc] initWithItemSize: typeSize capacity: 1]; [_returnValue increaseCountBy: 1]; } |
︙ | ︙ | |||
86 87 88 89 90 91 92 | [_methodSignature release]; [_arguments release]; [_returnValue release]; [super dealloc]; } | | < < | < < < < < < < < < | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | [_methodSignature release]; [_arguments release]; [_returnValue release]; [super dealloc]; } - (void)setArgument: (const void *)buffer atIndex: (size_t)idx { OFMutableData *data = [_arguments objectAtIndex: idx]; memcpy(data.mutableItems, buffer, data.itemSize); } - (void)getArgument: (void *)buffer atIndex: (size_t)idx { OFData *data = [_arguments objectAtIndex: idx]; memcpy(buffer, data.items, data.itemSize); } - (void)setReturnValue: (const void *)buffer { memcpy(_returnValue.mutableItems, buffer, _returnValue.itemSize); } - (void)getReturnValue: (void *)buffer { memcpy(buffer, _returnValue.items, _returnValue.itemSize); } @end |
Modified src/OFJSONRepresentation.h from [eef7794ab0] to [2bd85161f3].
1 | /* | < < | > > > | > | > | | < > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" @class OFString; OF_ASSUME_NONNULL_BEGIN /** * @brief Options to change the behavior when creating a JSON representation. */ typedef enum { /** Optimize for readability */ OFJSONRepresentationOptionPretty = 0x01, /** Generate JSON5 */ OFJSONRepresentationOptionJSON5 = 0x02, OFJSONRepresentationOptionIsIdentifier = 0x10 } OFJSONRepresentationOptions; /** * @protocol OFJSONRepresentation * OFJSONRepresentation.h ObjFW/OFJSONRepresentation.h * * @brief A protocol implemented by classes that support encoding to a JSON * representation. |
︙ | ︙ | |||
43 44 45 46 47 48 49 | * @brief The JSON representation of the object as a string. */ @property (readonly, nonatomic) OFString *JSONRepresentation; /** * @brief Returns the JSON representation of the object as a string. * | | < < < < < < | > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | * @brief The JSON representation of the object as a string. */ @property (readonly, nonatomic) OFString *JSONRepresentation; /** * @brief Returns the JSON representation of the object as a string. * * @param options The options to use when creating a JSON representation * @return The JSON representation of the object as a string */ - (OFString *)JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options; @end OF_ASSUME_NONNULL_END |
Modified src/OFKernelEventObserver.h from [74da8f3153] to [21aebcf8a0].
1 | /* | < < | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #ifdef OF_HAVE_SOCKETS # import "OFSocket.h" #endif #ifdef OF_AMIGAOS # include <exec/types.h> # include <exec/tasks.h> #endif |
︙ | ︙ | |||
120 121 122 123 124 125 126 | @interface OFKernelEventObserver: OFObject { OFMutableArray OF_GENERIC(id <OFReadyForReadingObserving>) *_readObjects; OFMutableArray OF_GENERIC(id <OFReadyForWritingObserving>) *_writeObjects; id <OFKernelEventObserverDelegate> _Nullable _delegate; | | < < > > | | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | @interface OFKernelEventObserver: OFObject { OFMutableArray OF_GENERIC(id <OFReadyForReadingObserving>) *_readObjects; OFMutableArray OF_GENERIC(id <OFReadyForWritingObserving>) *_writeObjects; id <OFKernelEventObserverDelegate> _Nullable _delegate; #if defined(OF_AMIGAOS) struct Task *_waitingTask; ULONG _cancelSignal; #elif defined(OF_HAVE_PIPE) int _cancelFD[2]; #else OFSocketHandle _cancelFD[2]; struct sockaddr_in _cancelAddr; #endif #ifdef OF_AMIGAOS ULONG _execSignalMask; #endif OF_RESERVE_IVARS(OFKernelEventObserver, 4) } |
︙ | ︙ | |||
211 212 213 214 215 216 217 | /** * @brief Observes all objects until an event happens on an object or the * timeout is reached. * * @param timeInterval The time to wait for an event, in seconds */ | | | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | /** * @brief Observes all objects until an event happens on an object or the * timeout is reached. * * @param timeInterval The time to wait for an event, in seconds */ - (void)observeForTimeInterval: (OFTimeInterval)timeInterval; /** * @brief Observes all objects until an event happens on an object or the * specified date is reached. * * @param date The until which to observe */ |
︙ | ︙ |
Modified src/OFKernelEventObserver.m from [0cbb2bba17] to [8d008316fd].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | #include <errno.h> #import "OFKernelEventObserver.h" #import "OFArray.h" #import "OFData.h" #import "OFDate.h" | < < | | < < < < > > > > > > > < < < < < < < < < < < | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | #include <errno.h> #import "OFKernelEventObserver.h" #import "OFArray.h" #import "OFData.h" #import "OFDate.h" #ifdef HAVE_EPOLL # import "OFEpollKernelEventObserver.h" #endif #ifdef HAVE_KQUEUE # import "OFKqueueKernelEventObserver.h" #endif #ifdef HAVE_POLL # import "OFPollKernelEventObserver.h" #endif #ifdef HAVE_SELECT # import "OFSelectKernelEventObserver.h" #endif #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFStream.h" #import "OFStream+Private.h" #ifndef OF_HAVE_PIPE # import "OFStreamSocket.h" #endif #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" #ifdef OF_AMIGAOS # include <proto/exec.h> #endif @implementation OFKernelEventObserver @synthesize delegate = _delegate; #ifdef OF_AMIGAOS @synthesize execSignalMask = _execSignalMask; #endif + (void)initialize { if (self != [OFKernelEventObserver class]) return; if (!OFSocketInit()) @throw [OFInitializationFailedException exceptionWithClass: self]; } + (instancetype)observer { return [[[self alloc] init] autorelease]; |
︙ | ︙ | |||
111 112 113 114 115 116 117 | !defined(OF_NINTENDO_3DS) socklen_t cancelAddrLen; #endif _readObjects = [[OFMutableArray alloc] init]; _writeObjects = [[OFMutableArray alloc] init]; | | | | | | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | !defined(OF_NINTENDO_3DS) socklen_t cancelAddrLen; #endif _readObjects = [[OFMutableArray alloc] init]; _writeObjects = [[OFMutableArray alloc] init]; #if defined(OF_HAVE_PIPE) && !defined(OF_AMIGAOS) if (pipe(_cancelFD)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; #elif !defined(OF_AMIGAOS) _cancelFD[0] = _cancelFD[1] = socket(AF_INET, SOCK_DGRAM, 0); if (_cancelFD[0] == OFInvalidSocketHandle) @throw [OFInitializationFailedException exceptionWithClass: self.class]; _cancelAddr.sin_family = AF_INET; _cancelAddr.sin_port = 0; _cancelAddr.sin_addr.s_addr = inet_addr((void *)"127.0.0.1"); # ifdef OF_WII _cancelAddr.sin_len = 8; # endif # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) if (bind(_cancelFD[0], (struct sockaddr *)&_cancelAddr, sizeof(_cancelAddr)) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; cancelAddrLen = sizeof(_cancelAddr); if (OFGetSockName(_cancelFD[0], (struct sockaddr *)&_cancelAddr, &cancelAddrLen) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; # else for (;;) { uint16_t rnd = 0; int ret; while (rnd < 1024) rnd = (uint16_t)rand(); _cancelAddr.sin_port = OFToBigEndian16(rnd); ret = bind(_cancelFD[0], (struct sockaddr *)&_cancelAddr, sizeof(_cancelAddr)); if (ret == 0) break; if (OFSocketErrNo() != EADDRINUSE) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } # endif #endif } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { #if defined(OF_HAVE_PIPE) && !defined(OF_AMIGAOS) close(_cancelFD[0]); if (_cancelFD[1] != _cancelFD[0]) close(_cancelFD[1]); #elif !defined(OF_AMIGAOS) closesocket(_cancelFD[0]); if (_cancelFD[1] != _cancelFD[0]) closesocket(_cancelFD[1]); |
︙ | ︙ | |||
243 244 245 246 247 248 249 | } - (void)observe { [self observeForTimeInterval: -1]; } | | | < < > > | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | } - (void)observe { [self observeForTimeInterval: -1]; } - (void)observeForTimeInterval: (OFTimeInterval)timeInterval { OF_UNRECOGNIZED_SELECTOR } - (void)observeUntilDate: (OFDate *)date { [self observeForTimeInterval: date.timeIntervalSinceNow]; } - (void)cancel { #if defined(OF_AMIGAOS) Forbid(); if (_waitingTask != NULL) { Signal(_waitingTask, (1ul << _cancelSignal)); _waitingTask = NULL; } Permit(); #elif defined(OF_HAVE_PIPE) OFEnsure(write(_cancelFD[1], "", 1) > 0); #elif defined(OF_WII) OFEnsure(sendto(_cancelFD[1], "", 1, 0, (struct sockaddr *)&_cancelAddr, 8) > 0); #else OFEnsure(sendto(_cancelFD[1], (void *)"", 1, 0, (struct sockaddr *)&_cancelAddr, sizeof(_cancelAddr)) > 0); #endif } @end |
Modified src/OFKeyValueCoding.h from [fc58ab9799] to [06cc2c1de6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
59 60 61 62 63 64 65 | /** * @brief Set the value for the specified key. * * @param value The value for the specified key * @param key The key of the value to set */ | | < | < | < | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | /** * @brief Set the value for the specified key. * * @param value The value for the specified key * @param key The key of the value to set */ - (void)setValue: (nullable id)value forKey: (OFString *)key; /** * @brief Set the value for the specified key path. * * @param value The value for the specified key path * @param keyPath The key path of the value to set */ - (void)setValue: (nullable id)value forKeyPath: (OFString *)keyPath; /** * @brief This is called by @ref setValue:forKey: if the specified key does not * exist. * * By default, this throws an @ref OFUndefinedKeyException. * * @param value The value for the specified undefined key * @param key The undefined key of the value to set */ - (void)setValue: (nullable id)value forUndefinedKey: (OFString *)key; /** * @brief This is called by @ref setValue:forKey: if the specified key is a * scalar, but the value specified is `nil`. * * By default, this throws an @ref OFInvalidArgumentException. * * @param key The key for which the value `nil` was specified */ - (void)setNilValueForKey: (OFString *)key; @end OF_ASSUME_NONNULL_END |
Modified src/OFKqueueKernelEventObserver.h from [bfbe37eedb] to [79cac968ba].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFKqueueKernelEventObserver.m from [56c8bac78d] to [bcb05813e9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
32 33 34 35 36 37 38 | #import "OFKqueueKernelEventObserver.h" #import "OFArray.h" #import "OFInitializationFailedException.h" #import "OFObserveFailedException.h" #import "OFOutOfRangeException.h" | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #import "OFKqueueKernelEventObserver.h" #import "OFArray.h" #import "OFInitializationFailedException.h" #import "OFObserveFailedException.h" #import "OFOutOfRangeException.h" #define eventListSize 64 @implementation OFKqueueKernelEventObserver - (instancetype)init { self = [super init]; @try { |
︙ | ︙ | |||
85 86 87 88 89 90 91 | { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForReading; event.filter = EVFILT_READ; event.flags = EV_ADD; | > > | > | < < < > > | > | < < < | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForReading; event.filter = EVFILT_READ; event.flags = EV_ADD; /* * Ugly hack required for NetBSD: NetBSD used `intptr_t` for udata, but * switched this to `void *` in NetBSD 10. */ event.udata = (__typeof__(event.udata))object; if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; [super addObjectForReading: object]; } - (void)addObjectForWriting: (id <OFReadyForWritingObserving>)object { struct kevent event; memset(&event, 0, sizeof(event)); event.ident = object.fileDescriptorForWriting; event.filter = EVFILT_WRITE; event.flags = EV_ADD; /* * Ugly hack required for NetBSD: NetBSD used `intptr_t` for udata, but * switched this to `void *` in NetBSD 10. */ event.udata = (__typeof__(event.udata))object; if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; [super addObjectForWriting: object]; } |
︙ | ︙ | |||
151 152 153 154 155 156 157 | if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; [super removeObjectForWriting: object]; } | | | | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | if (kevent(_kernelQueue, &event, 1, NULL, 0, NULL) != 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; [super removeObjectForWriting: object]; } - (void)observeForTimeInterval: (OFTimeInterval)timeInterval { struct timespec timeout; struct kevent eventList[eventListSize]; int events; if ([self of_processReadBuffers]) return; timeout.tv_sec = (time_t)timeInterval; timeout.tv_nsec = (long)((timeInterval - timeout.tv_sec) * 1000000000); events = kevent(_kernelQueue, NULL, 0, eventList, eventListSize, (timeInterval != -1 ? &timeout : NULL)); if (events < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: errno]; for (int i = 0; i < events; i++) { void *pool; if (eventList[i].flags & EV_ERROR) @throw [OFObserveFailedException exceptionWithObserver: self errNo: (int)eventList[i].data]; if (eventList[i].ident == (uintptr_t)_cancelFD[0]) { char buffer; assert(eventList[i].filter == EVFILT_READ); OFEnsure(read(_cancelFD[0], &buffer, 1) == 1); continue; } pool = objc_autoreleasePoolPush(); switch (eventList[i].filter) { |
︙ | ︙ |
Modified src/OFLHAArchive.h from [75a10f411b] to [eaf15d177e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | * * @brief A class for accessing and manipulating LHA files. */ OF_SUBCLASSING_RESTRICTED @interface OFLHAArchive: OFObject { OFStream *_stream; | < < < < | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | * * @brief A class for accessing and manipulating LHA files. */ OF_SUBCLASSING_RESTRICTED @interface OFLHAArchive: OFObject { OFStream *_stream; uint_least8_t _mode; OFStringEncoding _encoding; OFStream *_Nullable _lastReturnedStream; } /** * @brief The encoding to use for the archive. Defaults to ISO 8859-1. */ @property (nonatomic) OFStringEncoding encoding; /** * @brief A stream for reading the current entry. * * @note This is only available in read mode. * * @note The returned stream conforms to @ref OFReadyForReadingObserving if the |
︙ | ︙ | |||
63 64 65 66 67 68 69 | * @param stream A stream from which the LHA archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFLHAArchive */ | | < | < | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | * @param stream A stream from which the LHA archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFLHAArchive */ + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode; #ifdef OF_HAVE_FILES /** * @brief Creates a new OFLHAArchive object with the specified file. * * @param path The path to the LHA file * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFLHAArchive */ + (instancetype)archiveWithPath: (OFString *)path mode: (OFString *)mode; #endif - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFLHAArchive object with the * specified stream. |
︙ | ︙ | |||
107 108 109 110 111 112 113 | * * @param path The path to the LHA file * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFLHAArchive */ | | < | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | * * @param path The path to the LHA file * @param mode The mode for the LHA file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFLHAArchive */ - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode; #endif /** * @brief Returns the next entry from the LHA archive or `nil` if all entries * have been read. * * @note This is only available in read mode. |
︙ | ︙ |
Modified src/OFLHAArchive.m from [d4b33ee3bc] to [5dc375ab00].
1 | /* | < < | > > > < < > > > > > > | | | | < | < | < | < | < | | | | < | | | < | < | < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFLHAArchive.h" #import "OFLHAArchiveEntry.h" #import "OFLHAArchiveEntry+Private.h" #import "OFCRC16.h" #ifdef OF_HAVE_FILES # import "OFFile.h" #endif #import "OFLHADecompressingStream.h" #import "OFStream.h" #import "OFSeekableStream.h" #import "OFString.h" #import "OFChecksumMismatchException.h" #import "OFInvalidArgumentException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" enum { modeRead, modeWrite, modeAppend }; OF_DIRECT_MEMBERS @interface OFLHAArchiveFileReadStream: OFStream <OFReadyForReadingObserving> { OFStream *_stream, *_decompressedStream; OFLHAArchiveEntry *_entry; uint32_t _toRead, _bytesConsumed; uint16_t _CRC16; bool _atEndOfStream, _skipped; } - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFLHAArchiveEntry *)entry; - (void)of_skip; @end OF_DIRECT_MEMBERS @interface OFLHAArchiveFileWriteStream: OFStream <OFReadyForWritingObserving> { OFMutableLHAArchiveEntry *_entry; OFStringEncoding _encoding; OFSeekableStream *_stream; OFFileOffset _headerOffset; uint32_t _bytesWritten; uint16_t _CRC16; } - (instancetype)of_initWithStream: (OFSeekableStream *)stream entry: (OFLHAArchiveEntry *)entry encoding: (OFStringEncoding)encoding; @end @implementation OFLHAArchive @synthesize encoding = _encoding; + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode { return [[[self alloc] initWithStream: stream mode: mode] autorelease]; } #ifdef OF_HAVE_FILES + (instancetype)archiveWithPath: (OFString *)path mode: (OFString *)mode { return [[[self alloc] initWithPath: path mode: mode] autorelease]; } #endif - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode { self = [super init]; @try { _stream = [stream retain]; if ([mode isEqual: @"r"]) _mode = modeRead; else if ([mode isEqual: @"w"]) _mode = modeWrite; else if ([mode isEqual: @"a"]) _mode = modeAppend; else @throw [OFInvalidArgumentException exception]; if ((_mode == modeWrite || _mode == modeAppend) && ![_stream isKindOfClass: [OFSeekableStream class]]) @throw [OFInvalidArgumentException exception]; if (_mode == modeAppend) [(OFSeekableStream *)_stream seekToOffset: 0 whence: SEEK_END]; _encoding = OFStringEncodingISO8859_1; } @catch (id e) { [self release]; @throw e; } return self; } #ifdef OF_HAVE_FILES - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode { OFFile *file; if ([mode isEqual: @"a"]) file = [[OFFile alloc] initWithPath: path mode: @"r+"]; else file = [[OFFile alloc] initWithPath: path mode: mode]; @try { self = [self initWithStream: file mode: mode]; } @finally { [file release]; } return self; } #endif |
︙ | ︙ | |||
162 163 164 165 166 167 168 | - (OFLHAArchiveEntry *)nextEntry { OFLHAArchiveEntry *entry; char header[21]; size_t headerLen; | | | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | - (OFLHAArchiveEntry *)nextEntry { OFLHAArchiveEntry *entry; char header[21]; size_t headerLen; if (_mode != modeRead) @throw [OFInvalidArgumentException exception]; [(OFLHAArchiveFileReadStream *)_lastReturnedStream of_skip]; @try { [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ |
︙ | ︙ | |||
203 204 205 206 207 208 209 | entry: entry]; return entry; } - (OFStream *)streamForReadingCurrentEntry { | | | < | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | entry: entry]; return entry; } - (OFStream *)streamForReadingCurrentEntry { if (_mode != modeRead) @throw [OFInvalidArgumentException exception]; if (_lastReturnedStream == nil) @throw [OFInvalidArgumentException exception]; return [[(OFLHAArchiveFileReadStream *)_lastReturnedStream retain] autorelease]; } - (OFStream *)streamForWritingEntry: (OFLHAArchiveEntry *)entry { OFString *compressionMethod; if (_mode != modeWrite && _mode != modeAppend) @throw [OFInvalidArgumentException exception]; compressionMethod = entry.compressionMethod; if (![compressionMethod isEqual: @"-lh0-"] && ![compressionMethod isEqual: @"-lhd-"]) @throw [OFNotImplementedException exceptionWithSelector: _cmd |
︙ | ︙ | |||
323 324 325 326 327 328 329 | { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } | | < | < | | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { size_t ret; if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) return 0; if (_stream.atEndOfStream && !_decompressedStream.hasDataInReadBuffer) @throw [OFTruncatedDataException exception]; if (length > _toRead) length = _toRead; ret = [_decompressedStream readIntoBuffer: buffer length: length]; _toRead -= ret; _CRC16 = OFCRC16(_CRC16, buffer, ret); if (_toRead == 0) { _atEndOfStream = true; if (_CRC16 != _entry.CRC16) { OFString *actualChecksum = [OFString stringWithFormat: @"%04" PRIX16, _CRC16]; |
︙ | ︙ | |||
404 405 406 407 408 409 410 | toRead = _entry.compressedSize - decompressingStream.bytesConsumed; stream = _stream; } if ([stream isKindOfClass: [OFSeekableStream class]] && | | | | < | 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 | toRead = _entry.compressedSize - decompressingStream.bytesConsumed; stream = _stream; } if ([stream isKindOfClass: [OFSeekableStream class]] && (sizeof(OFFileOffset) > 4 || toRead < INT32_MAX)) [(OFSeekableStream *)stream seekToOffset: (OFFileOffset)toRead whence: SEEK_CUR]; else { while (toRead > 0) { char buffer[512]; size_t min = toRead; if (min > 512) min = 512; toRead -= [stream readIntoBuffer: buffer length: min]; } } _toRead = 0; _skipped = true; } |
︙ | ︙ | |||
444 445 446 447 448 449 450 | [super close]; } @end @implementation OFLHAArchiveFileWriteStream - (instancetype)of_initWithStream: (OFSeekableStream *)stream entry: (OFLHAArchiveEntry *)entry | | | < | < | 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 | [super close]; } @end @implementation OFLHAArchiveFileWriteStream - (instancetype)of_initWithStream: (OFSeekableStream *)stream entry: (OFLHAArchiveEntry *)entry encoding: (OFStringEncoding)encoding { self = [super init]; @try { _entry = [entry mutableCopy]; _encoding = encoding; _headerOffset = [stream seekToOffset: 0 whence: SEEK_CUR]; [_entry of_writeToStream: stream encoding: _encoding]; /* * Retain stream last, so that -[close] called by -[dealloc] * doesn't write in case of an error. */ _stream = [stream retain]; } @catch (id e) { |
︙ | ︙ | |||
480 481 482 483 484 485 486 | [self close]; [_entry release]; [super dealloc]; } | | < < < | < > > | | > > > | | | | | < | < | < | < | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 | [self close]; [_entry release]; [super dealloc]; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (UINT32_MAX - _bytesWritten < length) @throw [OFOutOfRangeException exception]; @try { [_stream writeBuffer: buffer length: length]; } @catch (OFWriteFailedException *e) { OFEnsure(e.bytesWritten <= length); _bytesWritten += (uint32_t)e.bytesWritten; _CRC16 = OFCRC16(_CRC16, buffer, e.bytesWritten); if (e.errNo == EWOULDBLOCK || e.errNo == EAGAIN) return e.bytesWritten; @throw e; } _bytesWritten += (uint32_t)length; _CRC16 = OFCRC16(_CRC16, buffer, length); return length; } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; return _stream.atEndOfStream; } - (int)fileDescriptorForWriting { return ((id <OFReadyForWritingObserving>)_stream) .fileDescriptorForWriting; } - (void)close { OFFileOffset offset; if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; _entry.uncompressedSize = _bytesWritten; _entry.compressedSize = _bytesWritten; _entry.CRC16 = _CRC16; offset = [_stream seekToOffset: 0 whence: SEEK_CUR]; [_stream seekToOffset: _headerOffset whence: SEEK_SET]; [_entry of_writeToStream: _stream encoding: _encoding]; [_stream seekToOffset: offset whence: SEEK_SET]; [_stream release]; _stream = nil; [super close]; } @end |
Modified src/OFLHAArchiveEntry+Private.h from [085a1438c0] to [dc492f96c5].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | OF_ASSUME_NONNULL_BEGIN OF_DIRECT_MEMBERS @interface OFLHAArchiveEntry () - (instancetype)of_initWithHeader: (char [_Nonnull 21])header stream: (OFStream *)stream | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | OF_ASSUME_NONNULL_BEGIN OF_DIRECT_MEMBERS @interface OFLHAArchiveEntry () - (instancetype)of_initWithHeader: (char [_Nonnull 21])header stream: (OFStream *)stream encoding: (OFStringEncoding)encoding OF_METHOD_FAMILY(init); - (void)of_writeToStream: (OFStream *)stream encoding: (OFStringEncoding)encoding; @end OF_ASSUME_NONNULL_END |
Modified src/OFLHAArchiveEntry.h from [091b8c9db3] to [e47bb8e429].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFLHAArchiveEntry.m from [61acef2124] to [45c1be7d3b].
1 | /* | < < | > < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "OFLHAArchiveEntry.h" #import "OFLHAArchiveEntry+Private.h" #import "OFArray.h" #import "OFCRC16.h" #import "OFData.h" #import "OFDate.h" #import "OFNumber.h" #import "OFStream.h" #import "OFString.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFUnsupportedVersionException.h" @implementation OFLHAArchiveEntry static OFDate * |
︙ | ︙ | |||
53 54 55 56 57 58 59 | return [OFDate dateWithLocalDateString: dateString format: @"%Y-%m-%d %H:%M:%S"]; } static void parseFileNameExtension(OFLHAArchiveEntry *entry, OFData *extension, | | | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | return [OFDate dateWithLocalDateString: dateString format: @"%Y-%m-%d %H:%M:%S"]; } static void parseFileNameExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { [entry->_fileName release]; entry->_fileName = nil; entry->_fileName = [[OFString alloc] initWithCString: (char *)extension.items + 1 encoding: encoding length: [extension count] - 1]; } static void parseDirectoryNameExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { void *pool = objc_autoreleasePoolPush(); OFMutableData *data = [[extension mutableCopy] autorelease]; char *items = data.mutableItems; size_t count = data.count; OFMutableString *directoryName; |
︙ | ︙ | |||
97 98 99 100 101 102 103 | entry->_directoryName = [directoryName copy]; objc_autoreleasePoolPop(pool); } static void parseCommentExtension(OFLHAArchiveEntry *entry, OFData *extension, | | | | | | | | | | | | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | entry->_directoryName = [directoryName copy]; objc_autoreleasePoolPop(pool); } static void parseCommentExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { [entry->_fileComment release]; entry->_fileComment = nil; entry->_fileComment = [[OFString alloc] initWithCString: (char *)extension.items + 1 encoding: encoding length: extension.count - 1]; } static void parsePermissionsExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { uint16_t mode; if (extension.count != 3) @throw [OFInvalidFormatException exception]; memcpy(&mode, (char *)extension.items + 1, 2); mode = OFFromLittleEndian16(mode); [entry->_mode release]; entry->_mode = nil; entry->_mode = [[OFNumber alloc] initWithUnsignedShort: mode]; } static void parseGIDUIDExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { uint16_t UID, GID; if (extension.count != 5) @throw [OFInvalidFormatException exception]; memcpy(&GID, (char *)extension.items + 1, 2); GID = OFFromLittleEndian16(GID); memcpy(&UID, (char *)extension.items + 3, 2); UID = OFFromLittleEndian16(UID); [entry->_GID release]; entry->_GID = nil; [entry->_UID release]; entry->_UID = nil; entry->_GID = [[OFNumber alloc] initWithUnsignedShort: GID]; entry->_UID = [[OFNumber alloc] initWithUnsignedShort: UID]; } static void parseGroupExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { [entry->_group release]; entry->_group = nil; entry->_group = [[OFString alloc] initWithCString: (char *)extension.items + 1 encoding: encoding length: extension.count - 1]; } static void parseOwnerExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { [entry->_owner release]; entry->_owner = nil; entry->_owner = [[OFString alloc] initWithCString: (char *)extension.items + 1 encoding: encoding length: extension.count - 1]; } static void parseModificationDateExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding) { uint32_t modificationDate; if (extension.count != 5) @throw [OFInvalidFormatException exception]; memcpy(&modificationDate, (char *)extension.items + 1, 4); modificationDate = OFFromLittleEndian32(modificationDate); [entry->_modificationDate release]; entry->_modificationDate = nil; entry->_modificationDate = [[OFDate alloc] initWithTimeIntervalSince1970: modificationDate]; } static bool parseExtension(OFLHAArchiveEntry *entry, OFData *extension, OFStringEncoding encoding, bool allowFileName) { void (*function)(OFLHAArchiveEntry *, OFData *, OFStringEncoding) = NULL; switch (*(char *)[extension itemAtIndex: 0]) { case 0x01: if (allowFileName) function = parseFileNameExtension; break; |
︙ | ︙ | |||
240 241 242 243 244 245 246 | function(entry, extension, encoding); return true; } static void readExtensions(OFLHAArchiveEntry *entry, OFStream *stream, | | | 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | function(entry, extension, encoding); return true; } static void readExtensions(OFLHAArchiveEntry *entry, OFStream *stream, OFStringEncoding encoding, bool allowFileName) { uint16_t size; while ((size = [stream readLittleEndianInt16]) > 0) { OFData *extension; if (size < 2) |
︙ | ︙ | |||
265 266 267 268 269 270 271 | entry->_compressedSize -= size; } } } static void | | < | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | entry->_compressedSize -= size; } } } static void getFileNameAndDirectoryName(OFLHAArchiveEntry *entry, OFStringEncoding encoding, const char **fileName, size_t *fileNameLength, const char **directoryName, size_t *directoryNameLength) { OFMutableData *data; char *cString; size_t length; size_t pos; |
︙ | ︙ | |||
331 332 333 334 335 336 337 | } return self; } - (instancetype)of_initWithHeader: (char [21])header stream: (OFStream *)stream | | | | | | | 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | } return self; } - (instancetype)of_initWithHeader: (char [21])header stream: (OFStream *)stream encoding: (OFStringEncoding)encoding { self = [super init]; @try { uint32_t date; _compressionMethod = [[OFString alloc] initWithCString: header + 2 encoding: OFStringEncodingASCII length: 5]; memcpy(&_compressedSize, header + 7, 4); _compressedSize = OFFromLittleEndian32(_compressedSize); memcpy(&_uncompressedSize, header + 11, 4); _uncompressedSize = OFFromLittleEndian32(_uncompressedSize); memcpy(&date, header + 15, 4); date = OFFromLittleEndian32(date); _headerLevel = header[20]; _extensions = [[OFMutableArray alloc] init]; switch (_headerLevel) { case 0: case 1:; |
︙ | ︙ | |||
553 554 555 556 557 558 559 | - (OFArray OF_GENERIC(OFData *) *)extensions { return _extensions; } - (void)of_writeToStream: (OFStream *)stream | | | | | | < | | < | | < | | < | | < | | < | < | | < | < | | < | | < | | < | | < | | < | | < | | < | | < | | < | | < | | < | < | | | | 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 | - (OFArray OF_GENERIC(OFData *) *)extensions { return _extensions; } - (void)of_writeToStream: (OFStream *)stream encoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); OFMutableData *data = [OFMutableData dataWithCapacity: 24]; const char *fileName, *directoryName; size_t fileNameLength, directoryNameLength; uint16_t tmp16; uint32_t tmp32; size_t headerSize; if ([_compressionMethod cStringLengthWithEncoding: OFStringEncodingASCII] != 5) @throw [OFInvalidArgumentException exception]; getFileNameAndDirectoryName(self, encoding, &fileName, &fileNameLength, &directoryName, &directoryNameLength); if (fileNameLength > UINT16_MAX - 3 || directoryNameLength > UINT16_MAX - 3) @throw [OFOutOfRangeException exception]; /* Length. Filled in after we're done. */ [data increaseCountBy: 2]; [data addItems: [_compressionMethod cStringWithEncoding: OFStringEncodingASCII] count: 5]; tmp32 = OFToLittleEndian32(_compressedSize); [data addItems: &tmp32 count: sizeof(tmp32)]; tmp32 = OFToLittleEndian32(_uncompressedSize); [data addItems: &tmp32 count: sizeof(tmp32)]; tmp32 = OFToLittleEndian32((uint32_t)_date.timeIntervalSince1970); [data addItems: &tmp32 count: sizeof(tmp32)]; /* Reserved */ [data increaseCountBy: 1]; /* Header level */ [data addItem: "\x02"]; /* CRC16 */ tmp16 = OFToLittleEndian16(_CRC16); [data addItems: &tmp16 count: sizeof(tmp16)]; /* Operating system identifier */ [data addItem: "U"]; /* Common header. Contains CRC16, which is written at the end. */ tmp16 = OFToLittleEndian16(5); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x00"]; [data increaseCountBy: 2]; tmp16 = OFToLittleEndian16((uint16_t)fileNameLength + 3); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x01"]; [data addItems: fileName count: fileNameLength]; if (directoryNameLength > 0) { tmp16 = OFToLittleEndian16((uint16_t)directoryNameLength + 3); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x02"]; [data addItems: directoryName count: directoryNameLength]; } if (_fileComment != nil) { size_t fileCommentLength = [_fileComment cStringLengthWithEncoding: encoding]; if (fileCommentLength > UINT16_MAX - 3) @throw [OFOutOfRangeException exception]; tmp16 = OFToLittleEndian16((uint16_t)fileCommentLength + 3); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x3F"]; [data addItems: [_fileComment cStringWithEncoding: encoding] count: fileCommentLength]; } if (_mode != nil) { tmp16 = OFToLittleEndian16(5); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x50"]; tmp16 = OFToLittleEndian16(_mode.unsignedShortValue); [data addItems: &tmp16 count: sizeof(tmp16)]; } if (_UID != nil || _GID != nil) { if (_UID == nil || _GID == nil) @throw [OFInvalidArgumentException exception]; tmp16 = OFToLittleEndian16(7); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x51"]; tmp16 = OFToLittleEndian16(_GID.unsignedShortValue); [data addItems: &tmp16 count: sizeof(tmp16)]; tmp16 = OFToLittleEndian16(_UID.unsignedShortValue); [data addItems: &tmp16 count: sizeof(tmp16)]; } if (_group != nil) { size_t groupLength = [_group cStringLengthWithEncoding: encoding]; if (groupLength > UINT16_MAX - 3) @throw [OFOutOfRangeException exception]; tmp16 = OFToLittleEndian16((uint16_t)groupLength + 3); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x52"]; [data addItems: [_group cStringWithEncoding: encoding] count: groupLength]; } if (_owner != nil) { size_t ownerLength = [_owner cStringLengthWithEncoding: encoding]; if (ownerLength > UINT16_MAX - 3) @throw [OFOutOfRangeException exception]; tmp16 = OFToLittleEndian16((uint16_t)ownerLength + 3); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x53"]; [data addItems: [_owner cStringWithEncoding: encoding] count: ownerLength]; } if (_modificationDate != nil) { tmp16 = OFToLittleEndian16(7); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItem: "\x54"]; tmp32 = OFToLittleEndian32( (uint32_t)_modificationDate.timeIntervalSince1970); [data addItems: &tmp32 count: sizeof(tmp32)]; } for (OFData *extension in _extensions) { size_t extensionLength = extension.count; if (extension.itemSize != 1) @throw [OFInvalidArgumentException exception]; if (extensionLength > UINT16_MAX - 2) @throw [OFOutOfRangeException exception]; tmp16 = OFToLittleEndian16((uint16_t)extensionLength + 2); [data addItems: &tmp16 count: sizeof(tmp16)]; [data addItems: extension.items count: extension.count]; } /* Zero-length extension to terminate */ [data increaseCountBy: 2]; headerSize = data.count; if (headerSize > UINT16_MAX) @throw [OFOutOfRangeException exception]; /* Now fill in the size and CRC16 for the entire header */ tmp16 = OFToLittleEndian16(headerSize); memcpy([data mutableItemAtIndex: 0], &tmp16, sizeof(tmp16)); tmp16 = OFCRC16(0, data.items, data.count); tmp16 = OFToLittleEndian16(tmp16); memcpy([data mutableItemAtIndex: 27], &tmp16, sizeof(tmp16)); [stream writeData: data]; objc_autoreleasePoolPop(pool); } |
︙ | ︙ |
Modified src/OFLHADecompressingStream.h from [cc62626ce1] to [1061027b73].
1 | /* | < < | > | | > | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFStream.h" #import "OFHuffmanTree.h" OF_ASSUME_NONNULL_BEGIN #define OFLHADecompressingStreamBufferSize 4096 OF_DIRECT_MEMBERS @interface OFLHADecompressingStream: OFStream { OFStream *_stream; uint8_t _distanceBits, _dictionaryBits; unsigned char _buffer[OFLHADecompressingStreamBufferSize]; uint32_t _bytesConsumed; uint16_t _bufferIndex, _bufferLength; uint8_t _byte; uint8_t _bitIndex, _savedBitsLength; uint16_t _savedBits; unsigned char *_slidingWindow; uint32_t _slidingWindowIndex, _slidingWindowMask; int _state; uint16_t _symbolsLeft; OFHuffmanTree _Nullable _codeLenTree; OFHuffmanTree _Nullable _litLenTree; OFHuffmanTree _Nullable _distTree; OFHuffmanTree _Nullable _treeIter; uint16_t _codesCount, _codesReceived; bool _currentIsExtendedLength, _skip; uint8_t *_Nullable _codesLengths; uint16_t _length; uint32_t _distance; } |
︙ | ︙ |
Modified src/OFLHADecompressingStream.m from [16b7cb0b85] to [1c43fdd671].
1 | /* | < < | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <assert.h> #import "OFLHADecompressingStream.h" #import "OFKernelEventObserver.h" #import "OFHuffmanTree.h" #import "OFInvalidFormatException.h" #import "OFNotOpenException.h" enum State { stateBlockHeader, stateCodeLenCodesCount, stateCodeLenTree, stateCodeLenTreeSingle, stateLitLenCodesCount, stateLitLenTree, stateLitLenTreeSingle, stateDistCodesCount, stateDistTree, stateDistTreeSingle, stateBlockLitLen, stateBlockDistLength, stateBlockDistLengthExtra, stateBlockLenDistPair }; @implementation OFLHADecompressingStream @synthesize bytesConsumed = _bytesConsumed; static OF_INLINE bool tryReadBits(OFLHADecompressingStream *stream, uint16_t *bits, uint8_t count) { uint16_t ret = stream->_savedBits; assert(stream->_savedBitsLength < count); for (uint_fast8_t i = stream->_savedBitsLength; i < count; i++) { if OF_UNLIKELY (stream->_bitIndex == 8) { if OF_LIKELY (stream->_bufferIndex < stream->_bufferLength) stream->_byte = stream->_buffer[stream->_bufferIndex++]; else { const size_t bufferLength = OFLHADecompressingStreamBufferSize; size_t length = [stream->_stream readIntoBuffer: stream->_buffer length: bufferLength]; stream->_bytesConsumed += (uint32_t)length; if OF_UNLIKELY (length < 1) { |
︙ | ︙ | |||
106 107 108 109 110 111 112 | /* 0-7 address the bit, 8 means fetch next byte */ _bitIndex = 8; _distanceBits = distanceBits; _dictionaryBits = dictionaryBits; _slidingWindowMask = (1u << dictionaryBits) - 1; | < | > > | | | > > | | | | | | | | | | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | /* 0-7 address the bit, 8 means fetch next byte */ _bitIndex = 8; _distanceBits = distanceBits; _dictionaryBits = dictionaryBits; _slidingWindowMask = (1u << dictionaryBits) - 1; _slidingWindow = OFAllocMemory(_slidingWindowMask + 1, 1); memset(_slidingWindow, ' ', _slidingWindowMask + 1); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_stream != nil) [self close]; OFFreeMemory(_slidingWindow); if (_codeLenTree != NULL) OFHuffmanTreeFree(_codeLenTree); if (_litLenTree != NULL) OFHuffmanTreeFree(_litLenTree); if (_distTree != NULL) OFHuffmanTreeFree(_distTree); OFFreeMemory(_codesLengths); [super dealloc]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer_ length: (size_t)length { unsigned char *buffer = buffer_; uint16_t bits = 0, value = 0; size_t bytesWritten = 0; if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_stream.atEndOfStream && _bufferLength - _bufferIndex == 0 && _state == stateBlockHeader) return 0; start: switch ((enum State)_state) { case stateBlockHeader: if OF_UNLIKELY (!tryReadBits(self, &bits, 16)) return bytesWritten; _symbolsLeft = bits; _state = stateCodeLenCodesCount; goto start; case stateCodeLenCodesCount: if OF_UNLIKELY (!tryReadBits(self, &bits, 5)) return bytesWritten; if OF_UNLIKELY (bits > 20) @throw [OFInvalidFormatException exception]; if OF_UNLIKELY (bits == 0) { _state = stateCodeLenTreeSingle; goto start; } _codesCount = bits; _codesReceived = 0; _codesLengths = OFAllocZeroedMemory(bits, 1); _skip = true; _state = stateCodeLenTree; goto start; case stateCodeLenTree: while (_codesReceived < _codesCount) { if OF_UNLIKELY (_currentIsExtendedLength) { if OF_UNLIKELY (!tryReadBits(self, &bits, 1)) return bytesWritten; if OF_UNLIKELY (bits == 0) { _codesReceived++; |
︙ | ︙ | |||
219 220 221 222 223 224 225 | if OF_UNLIKELY (bits == 7) { _currentIsExtendedLength = true; continue; } else _codesReceived++; } | | | | | | | | | | | | | | | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | if OF_UNLIKELY (bits == 7) { _currentIsExtendedLength = true; continue; } else _codesReceived++; } _codeLenTree = OFHuffmanTreeNew(_codesLengths, _codesCount); OFFreeMemory(_codesLengths); _codesLengths = NULL; _state = stateLitLenCodesCount; goto start; case stateCodeLenTreeSingle: if OF_UNLIKELY (!tryReadBits(self, &bits, 5)) return bytesWritten; _codeLenTree = OFHuffmanTreeNewSingle(bits); _state = stateLitLenCodesCount; goto start; case stateLitLenCodesCount: if OF_UNLIKELY (!tryReadBits(self, &bits, 9)) return bytesWritten; if OF_UNLIKELY (bits > 510) @throw [OFInvalidFormatException exception]; if OF_UNLIKELY (bits == 0) { OFHuffmanTreeFree(_codeLenTree); _codeLenTree = NULL; _state = stateLitLenTreeSingle; goto start; } _codesCount = bits; _codesReceived = 0; _codesLengths = OFAllocZeroedMemory(bits, 1); _skip = false; _treeIter = _codeLenTree; _state = stateLitLenTree; goto start; case stateLitLenTree: while (_codesReceived < _codesCount) { if OF_UNLIKELY (_skip) { uint16_t skipCount; switch (_codesLengths[_codesReceived]) { case 0: skipCount = 1; |
︙ | ︙ | |||
280 281 282 283 284 285 286 | if OF_UNLIKELY (!tryReadBits(self, &bits, 9)) return bytesWritten; skipCount = bits + 20; break; default: | | | | | | | | | | | | | | | | | | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | if OF_UNLIKELY (!tryReadBits(self, &bits, 9)) return bytesWritten; skipCount = bits + 20; break; default: OFEnsure(0); } if OF_UNLIKELY (_codesReceived + skipCount > _codesCount) @throw [OFInvalidFormatException exception]; for (uint_fast16_t j = 0; j < skipCount; j++) _codesLengths[_codesReceived++] = 0; _skip = false; continue; } if (!OFHuffmanTreeWalk(self, tryReadBits, &_treeIter, &value)) return bytesWritten; _treeIter = _codeLenTree; if (value < 3) { _codesLengths[_codesReceived] = value; _skip = true; } else _codesLengths[_codesReceived++] = value - 2; } _litLenTree = OFHuffmanTreeNew(_codesLengths, _codesCount); OFFreeMemory(_codesLengths); _codesLengths = NULL; OFHuffmanTreeFree(_codeLenTree); _codeLenTree = NULL; _state = stateDistCodesCount; goto start; case stateLitLenTreeSingle: if OF_UNLIKELY (!tryReadBits(self, &bits, 9)) return bytesWritten; _litLenTree = OFHuffmanTreeNewSingle(bits); _state = stateDistCodesCount; goto start; case stateDistCodesCount: if OF_UNLIKELY (!tryReadBits(self, &bits, _distanceBits)) return bytesWritten; if OF_UNLIKELY (bits > _dictionaryBits) @throw [OFInvalidFormatException exception]; if OF_UNLIKELY (bits == 0) { _state = stateDistTreeSingle; goto start; } _codesCount = bits; _codesReceived = 0; _codesLengths = OFAllocZeroedMemory(bits, 1); _treeIter = _codeLenTree; _state = stateDistTree; goto start; case stateDistTree: while (_codesReceived < _codesCount) { if OF_UNLIKELY (_currentIsExtendedLength) { if OF_UNLIKELY (!tryReadBits(self, &bits, 1)) return bytesWritten; if OF_UNLIKELY (bits == 0) { _codesReceived++; |
︙ | ︙ | |||
372 373 374 375 376 377 378 | if OF_UNLIKELY (bits == 7) { _currentIsExtendedLength = true; continue; } else _codesReceived++; } | | | | | | | | | | | | | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | if OF_UNLIKELY (bits == 7) { _currentIsExtendedLength = true; continue; } else _codesReceived++; } _distTree = OFHuffmanTreeNew(_codesLengths, _codesCount); OFFreeMemory(_codesLengths); _codesLengths = NULL; _treeIter = _litLenTree; _state = stateBlockLitLen; goto start; case stateDistTreeSingle: if OF_UNLIKELY (!tryReadBits(self, &bits, _distanceBits)) return bytesWritten; _distTree = OFHuffmanTreeNewSingle(bits); _treeIter = _litLenTree; _state = stateBlockLitLen; goto start; case stateBlockLitLen: if OF_UNLIKELY (_symbolsLeft == 0) { OFHuffmanTreeFree(_litLenTree); OFHuffmanTreeFree(_distTree); _litLenTree = _distTree = NULL; _state = stateBlockHeader; /* * We must return here, as there is no indication * whether this was the last block. Whoever called this * method needs to check if everything has been read * already and only call read again if that is not the * case. |
︙ | ︙ | |||
419 420 421 422 423 424 425 | return bytesWritten; } if OF_UNLIKELY (length == 0) return bytesWritten; | | | | | | < | | | | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | return bytesWritten; } if OF_UNLIKELY (length == 0) return bytesWritten; if OF_UNLIKELY (!OFHuffmanTreeWalk(self, tryReadBits, &_treeIter, &value)) return bytesWritten; if OF_LIKELY (value < 256) { buffer[bytesWritten++] = value; length--; _slidingWindow[_slidingWindowIndex] = value; _slidingWindowIndex = (_slidingWindowIndex + 1) & _slidingWindowMask; _symbolsLeft--; _treeIter = _litLenTree; } else { _length = value - 253; _treeIter = _distTree; _state = stateBlockDistLength; } goto start; case stateBlockDistLength: if OF_UNLIKELY (!OFHuffmanTreeWalk(self, tryReadBits, &_treeIter, &value)) return bytesWritten; _distance = value; _state = (value < 2 ? stateBlockLenDistPair : stateBlockDistLengthExtra); goto start; case stateBlockDistLengthExtra: if OF_UNLIKELY (!tryReadBits(self, &bits, _distance - 1)) return bytesWritten; _distance = bits + (1u << (_distance - 1)); _state = stateBlockLenDistPair; goto start; case stateBlockLenDistPair: for (uint_fast16_t i = 0; i < _length; i++) { uint32_t idx; if OF_UNLIKELY (length == 0) { _length -= i; return bytesWritten; } |
︙ | ︙ | |||
483 484 485 486 487 488 489 | _slidingWindowIndex = (_slidingWindowIndex + 1) & _slidingWindowMask; } _symbolsLeft--; _treeIter = _litLenTree; | | | | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 | _slidingWindowIndex = (_slidingWindowIndex + 1) & _slidingWindowMask; } _symbolsLeft--; _treeIter = _litLenTree; _state = stateBlockLitLen; goto start; } OF_UNREACHABLE } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; return (_stream.atEndOfStream && _bufferLength - _bufferIndex == 0 && _state == stateBlockHeader); } - (int)fileDescriptorForReading { return ((id <OFReadyForReadingObserving>)_stream) .fileDescriptorForReading; } |
︙ | ︙ |
Modified src/OFList.h from [75efc796d9] to [f2ae387af6].
1 | /* | < < | > | > > > > > > > > | | < | > > > > | > > > > > > > | > > | > > > > > | > > | > | > > > > > | < > > > > > | | | | < | < | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFCollection.h" #import "OFEnumerator.h" #import "OFSerialization.h" OF_ASSUME_NONNULL_BEGIN /** @file */ /* * Make clang's -Wdocumentation shut about about using @struct on someting it * thinks is not a struct. Doxygen requires it this way. */ #ifdef __clang__ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wdocumentation" #endif /** * @struct OFListItem OFList.h ObjFW/OFList.h * * @brief A list item. * * See @ref OFListItemNext, @ref OFListItemPrevious and @ref OFListItemObject. */ typedef struct _OFListItem *OFListItem; #ifdef __clang__ # pragma clang diagnostic pop #endif #ifdef __cplusplus extern "C" { #endif /*! * @brief Returns the next list item of the list item. * * @param listItem The list item for which the next list item should be returned * @return The next list item of the list item */ extern OFListItem _Nullable OFListItemNext(OFListItem _Nonnull listItem); /*! * @brief Returns the previous list item of the list item. * * @param listItem The list item for which the previous list item should be * returned * @return The previous list item of the list item */ extern OFListItem _Nullable OFListItemPrevious(OFListItem _Nonnull listItem); /*! * @brief Returns the object of the list item. * * @warning The returned object is not retained and autoreleased - this is the * caller's responsibility! * * @param listItem The list item for which the object should be returned * @return The object of the list item */ extern id _Nonnull OFListItemObject(OFListItem _Nonnull listItem); #ifdef __cplusplus } #endif /** * @class OFList OFList.h ObjFW/OFList.h * * @brief A class which provides easy to use double-linked lists. */ @interface OFList OF_GENERIC(ObjectType): OFObject <OFCopying, OFCollection, OFSerialization> #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif { OFListItem _Nullable _firstListItem; OFListItem _Nullable _lastListItem; size_t _count; unsigned long _mutations; OF_RESERVE_IVARS(OFList, 4) } /** * @brief The first list object of the list. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFListItem firstListItem; /** * @brief The first object of the list or `nil`. * * @warning The returned object is *not* retained and autoreleased for * performance reasons! */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) ObjectType firstObject; /** * @brief The last list object of the list. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFListItem lastListItem; /** * @brief The last object of the list or `nil`. * * @warning The returned object is *not* retained and autoreleased for * performance reasons! */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) ObjectType lastObject; /** * @brief Creates a new OFList. * * @return A new autoreleased OFList */ + (instancetype)list; /** * @brief Appends an object to the list. * * @param object The object to append * @return An OFListItem, needed to identify the object inside the list. * For example, if you want to remove an object from the list, you need * its OFListItem. */ - (OFListItem)appendObject: (ObjectType)object; /** * @brief Prepends an object to the list. * * @param object The object to prepend * @return An OFListItem, needed to identify the object inside the list. * For example, if you want to remove an object from the list, you need * its OFListItem. */ - (OFListItem)prependObject: (ObjectType)object; /** * @brief Inserts an object before another list object. * * @param object The object to insert * @param listItem The OFListItem of the object before which it should be * inserted * @return An OFListItem, needed to identify the object inside the list. * For example, if you want to remove an object from the list, you need * its OFListItem. */ - (OFListItem)insertObject: (ObjectType)object beforeListItem: (OFListItem)listItem; /** * @brief Inserts an object after another list object. * * @param object The object to insert * @param listItem The OFListItem of the object after which it should be * inserted * @return An OFListItem, needed to identify the object inside the list. * For example, if you want to remove an object from the list, you need * its OFListItem. */ - (OFListItem)insertObject: (ObjectType)object afterListItem: (OFListItem)listItem; /** * @brief Removes the object with the specified list object from the list. * * @param listItem The list object returned by append / prepend */ - (void)removeListItem: (OFListItem)listItem; /** * @brief Checks whether the list contains an object equal to the specified * object. * * @param object The object which is checked for being in the list * @return A boolean whether the list contains the specified object |
︙ | ︙ |
Modified src/OFList.m from [2cea85f754] to [18864abbc2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 | #import "OFList.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFArray.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" OF_DIRECT_MEMBERS @interface OFListEnumerator: OFEnumerator { OFList *_list; | > > > > > | > > > > > > > > > > > > > > > > > > | < | | > | | > > | > | | < | | | | | | | | < < < < < < | > | | > > > > | | | | | | | | | | < | < | | | < < < > > > | | | | | < | < | | | | | | | | | | | | | | | | | | | < | | | | | < | < | | | < < > | | < < < | | < | | | | | | | | | | | < | | | | | < | | | | | | | | | | | < | > | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | #import "OFList.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFArray.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" struct _OFListItem { struct _OFListItem *previous, *next; id object; }; OF_DIRECT_MEMBERS @interface OFListEnumerator: OFEnumerator { OFList *_list; OFListItem _Nullable _current; unsigned long _mutations; unsigned long *_Nullable _mutationsPtr; } - (instancetype)initWithList: (OFList *)list mutationsPointer: (unsigned long *)mutationsPtr; @end OFListItem OFListItemNext(OFListItem listItem) { return listItem->next; } OFListItem OFListItemPrevious(OFListItem listItem) { return listItem->previous; } id OFListItemObject(OFListItem listItem) { return listItem->object; } @implementation OFList @synthesize firstListItem = _firstListItem, lastListItem = _lastListItem; + (instancetype)list { return [[[self alloc] init] autorelease]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; for (OFXMLElement *child in [element elementsForNamespace: OFSerializationNS]) { void *pool2 = objc_autoreleasePoolPush(); [self appendObject: child.objectByDeserializing]; objc_autoreleasePoolPop(pool2); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { OFListItem next; for (OFListItem iter = _firstListItem; iter != NULL; iter = next) { [iter->object release]; next = iter->next; OFFreeMemory(iter); } [super dealloc]; } - (OFListItem)appendObject: (id)object { OFListItem listItem = OFAllocMemory(1, sizeof(*listItem)); listItem->object = [object retain]; listItem->next = NULL; listItem->previous = _lastListItem; if (_lastListItem != NULL) _lastListItem->next = listItem; _lastListItem = listItem; if (_firstListItem == NULL) _firstListItem = listItem; _count++; _mutations++; return listItem; } - (OFListItem)prependObject: (id)object { OFListItem listItem = OFAllocMemory(1, sizeof(*listItem)); listItem->object = [object retain]; listItem->next = _firstListItem; listItem->previous = NULL; if (_firstListItem != NULL) _firstListItem->previous = listItem; _firstListItem = listItem; if (_lastListItem == NULL) _lastListItem = listItem; _count++; _mutations++; return listItem; } - (OFListItem)insertObject: (id)object beforeListItem: (OFListItem)listItem { OFListItem newListItem = OFAllocMemory(1, sizeof(*newListItem)); newListItem->object = [object retain]; newListItem->next = listItem; newListItem->previous = listItem->previous; if (listItem->previous != NULL) listItem->previous->next = newListItem; listItem->previous = newListItem; if (listItem == _firstListItem) _firstListItem = newListItem; _count++; _mutations++; return newListItem; } - (OFListItem)insertObject: (id)object afterListItem: (OFListItem)listItem { OFListItem newListItem = OFAllocMemory(1, sizeof(*newListItem)); newListItem->object = [object retain]; newListItem->next = listItem->next; newListItem->previous = listItem; if (listItem->next != NULL) listItem->next->previous = newListItem; listItem->next = newListItem; if (listItem == _lastListItem) _lastListItem = newListItem; _count++; _mutations++; return newListItem; } - (void)removeListItem: (OFListItem)listItem { if (listItem->previous != NULL) listItem->previous->next = listItem->next; if (listItem->next != NULL) listItem->next->previous = listItem->previous; if (_firstListItem == listItem) _firstListItem = listItem->next; if (_lastListItem == listItem) _lastListItem = listItem->previous; _count--; _mutations++; [listItem->object release]; OFFreeMemory(listItem); } - (id)firstObject { return (_firstListItem != NULL ? _firstListItem->object : nil); } - (id)lastObject { return (_lastListItem != NULL ? _lastListItem->object : nil); } - (size_t)count { return _count; } - (bool)isEqual: (id)object { OFList *list; OFListItem iter, iter2; if (object == self) return true; if (![object isKindOfClass: [OFList class]]) return false; list = object; if (list.count != _count) return false; for (iter = _firstListItem, iter2 = list.firstListItem; iter != NULL && iter2 != NULL; iter = iter->next, iter2 = iter2->next) if (![iter->object isEqual: iter2->object]) return false; /* One is bigger than the other even though we checked the count */ assert(iter == NULL && iter2 == NULL); return true; } - (bool)containsObject: (id)object { if (_count == 0) return false; for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) if ([iter->object isEqual: object]) return true; return false; } - (bool)containsObjectIdenticalTo: (id)object { if (_count == 0) return false; for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) if (iter->object == object) return true; return false; } - (void)removeAllObjects { OFListItem next; _mutations++; for (OFListItem iter = _firstListItem; iter != NULL; iter = next) { [iter->object release]; next = iter->next; OFFreeMemory(iter); } _firstListItem = _lastListItem = NULL; } - (id)copy { OFList *copy = [[[self class] alloc] init]; OFListItem listItem = NULL, previous = NULL; @try { for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) { listItem = OFAllocMemory(1, sizeof(*listItem)); listItem->object = [iter->object retain]; listItem->next = NULL; listItem->previous = previous; if (copy->_firstListItem == NULL) copy->_firstListItem = listItem; if (previous != NULL) previous->next = listItem; copy->_count++; previous = listItem; } } @catch (id e) { [copy release]; @throw e; } copy->_lastListItem = listItem; return copy; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) OFHashAddHash(&hash, [iter->object hash]); OFHashFinalize(&hash); return hash; } - (OFString *)description { OFMutableString *ret; if (_count == 0) return @"[]"; ret = [OFMutableString stringWithString: @"[\n"]; for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) { void *pool = objc_autoreleasePoolPush(); [ret appendString: [iter->object description]]; if (iter->next != NULL) [ret appendString: @",\n"]; objc_autoreleasePoolPop(pool); } [ret replaceOccurrencesOfString: @"\n" withString: @"\n\t"]; [ret appendString: @"\n]"]; [ret makeImmutable]; return ret; } - (OFXMLElement *)XMLElementBySerializing { OFXMLElement *element = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS]; for (OFListItem iter = _firstListItem; iter != NULL; iter = iter->next) { void *pool = objc_autoreleasePoolPush(); [element addChild: [iter->object XMLElementBySerializing]]; objc_autoreleasePoolPop(pool); } return element; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { OFListItem listItem; memcpy(&listItem, state->extra, sizeof(listItem)); state->itemsPtr = objects; state->mutationsPtr = &_mutations; if (state->state == 0) { listItem = _firstListItem; state->state = 1; } for (int i = 0; i < count; i++) { if (listItem == NULL) return i; objects[i] = listItem->object; listItem = listItem->next; } memcpy(state->extra, &listItem, sizeof(listItem)); return count; } - (OFEnumerator *)objectEnumerator { return [[[OFListEnumerator alloc] initWithList: self mutationsPointer: &_mutations] autorelease]; } @end @implementation OFListEnumerator - (instancetype)initWithList: (OFList *)list mutationsPointer: (unsigned long *)mutationsPtr { self = [super init]; _list = [list retain]; _current = _list.firstListItem; _mutations = *mutationsPtr; _mutationsPtr = mutationsPtr; return self; } - (void)dealloc |
︙ | ︙ |
Modified src/OFLocale.h from [24af3246f9] to [fcc8f077d2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
43 44 45 46 47 48 49 | * * @brief A class for querying the locale and retrieving localized strings. */ OF_SUBCLASSING_RESTRICTED @interface OFLocale: OFObject { OFString *_Nullable _language, *_Nullable _territory; | | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | * * @brief A class for querying the locale and retrieving localized strings. */ OF_SUBCLASSING_RESTRICTED @interface OFLocale: OFObject { OFString *_Nullable _language, *_Nullable _territory; OFStringEncoding _encoding; OFString *_decimalPoint; OFMutableArray OF_GENERIC(OFDictionary OF_GENERIC(OFString *, id) *) *_localizedStrings; } #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nullable, nonatomic) OFLocale *currentLocale; @property (class, readonly, nullable, nonatomic) OFString *language; @property (class, readonly, nullable, nonatomic) OFString *territory; @property (class, readonly, nonatomic) OFStringEncoding encoding; @property (class, readonly, nullable, nonatomic) OFString *decimalPoint; #endif /** * @brief The language of the locale for messages. * * If the language is unknown, it is `nil`. |
︙ | ︙ | |||
79 80 81 82 83 84 85 | * @brief The native 8-bit string encoding of the locale for messages. * * This is useful to encode strings correctly for passing them to operating * system calls. * * If the native 8-bit encoding is unknown, UTF-8 is assumed. */ | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | * @brief The native 8-bit string encoding of the locale for messages. * * This is useful to encode strings correctly for passing them to operating * system calls. * * If the native 8-bit encoding is unknown, UTF-8 is assumed. */ @property (readonly, nonatomic) OFStringEncoding encoding; /** * @brief The decimal point of the system's locale. */ @property (readonly, nonatomic) OFString *decimalPoint; /** |
︙ | ︙ | |||
125 126 127 128 129 130 131 | * This is useful to encode strings correctly for passing them to operating * system calls. * * If the native 8-bit encoding is unknown, UTF-8 is assumed. * * @return The native 8-bit string encoding for the locale */ | | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | * This is useful to encode strings correctly for passing them to operating * system calls. * * If the native 8-bit encoding is unknown, UTF-8 is assumed. * * @return The native 8-bit string encoding for the locale */ + (OFStringEncoding)encoding; /** * @brief Returns the decimal point of the system's locale. * * @return The decimal point of the system's locale */ + (nullable OFString *)decimalPoint; |
︙ | ︙ | |||
150 151 152 153 154 155 156 | /** * @brief Initializes the current OFLocale. * * @warning This sets the locale via `setlocale()`! * * @warning You should never call this yourself, except if you do not use * @ref OFApplication. In this case, you need to allocate exactly one | | | 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | /** * @brief Initializes the current OFLocale. * * @warning This sets the locale via `setlocale()`! * * @warning You should never call this yourself, except if you do not use * @ref OFApplication. In this case, you need to allocate exactly one * instance of OFLocale, which will become the current locale, and * call this method. */ - (instancetype)init; #ifdef OF_HAVE_FILES /** * @brief Adds a directory to scan for language files. |
︙ | ︙ |
Modified src/OFLocale.m from [b6b16348ac] to [ccac2d9a08].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | #endif static OFLocale *currentLocale = nil; static OFDictionary *operatorPrecedences = nil; #ifndef OF_AMIGAOS static void | | | < | | | | > < | < | < | | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | #endif static OFLocale *currentLocale = nil; static OFDictionary *operatorPrecedences = nil; #ifndef OF_AMIGAOS static void parseLocale(char *locale, OFStringEncoding *encoding, OFString **language, OFString **territory) { locale = OFStrDup(locale); @try { OFStringEncoding enc = OFStringEncodingASCII; char *tmp; /* We don't care for extras behind the @ */ if ((tmp = strrchr(locale, '@')) != NULL) *tmp = '\0'; /* Encoding */ if ((tmp = strrchr(locale, '.')) != NULL) { *tmp++ = '\0'; @try { if (encoding != NULL) *encoding = OFStringEncodingParseName( [OFString stringWithCString: tmp encoding: enc]); } @catch (OFInvalidArgumentException *e) { } } /* Territory */ if ((tmp = strrchr(locale, '_')) != NULL) { *tmp++ = '\0'; if (territory != NULL) *territory = [OFString stringWithCString: tmp encoding: enc]; } if (language != NULL) *language = [OFString stringWithCString: locale encoding: enc]; } @finally { OFFreeMemory(locale); } } #endif static bool evaluateCondition(OFString *condition_, OFDictionary *variables) { OFMutableString *condition = [[condition_ mutableCopy] autorelease]; OFMutableArray *tokens, *operators, *stack; /* Empty condition is the fallback that's always true */ if (condition.length == 0) return true; /* * Dirty hack to allow not needing spaces after "!" or "(" and spaces * before ")". * TODO: Replace with a proper tokenizer. */ [condition replaceOccurrencesOfString: @"!" withString: @"! "]; [condition replaceOccurrencesOfString: @"(" withString: @"( "]; [condition replaceOccurrencesOfString: @")" withString: @" )"]; /* Substitute variables and convert to RPN first */ tokens = [OFMutableArray array]; operators = [OFMutableArray array]; for (OFString *token in [condition componentsSeparatedByString: @" " options: OFStringSkipEmptyComponents]) { unsigned precedence; OFUnichar c; if ([token isEqual: @"("]) { [operators addObject: @"("]; continue; } if ([token isEqual: @")"]) { |
︙ | ︙ | |||
197 198 199 200 201 202 203 | var = [OFNumber numberWithBool: [first isEqual: second]]; else if ([token isEqual: @"!="]) var = [OFNumber numberWithBool: ![first isEqual: second]]; else if ([token isEqual: @"<"]) var = [OFNumber numberWithBool: [first | | | | | | | | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | var = [OFNumber numberWithBool: [first isEqual: second]]; else if ([token isEqual: @"!="]) var = [OFNumber numberWithBool: ![first isEqual: second]]; else if ([token isEqual: @"<"]) var = [OFNumber numberWithBool: [first compare: second] == OFOrderedAscending]; else if ([token isEqual: @"<="]) var = [OFNumber numberWithBool: [first compare: second] != OFOrderedDescending]; else if ([token isEqual: @">"]) var = [OFNumber numberWithBool: [first compare: second] == OFOrderedDescending]; else if ([token isEqual: @">="]) var = [OFNumber numberWithBool: [first compare: second] != OFOrderedAscending]; else if ([token isEqual: @"+"]) var = [OFNumber numberWithDouble: [first doubleValue] + [second doubleValue]]; else if ([token isEqual: @"%"]) var = [OFNumber numberWithLongLong: [first longLongValue] % [second longLongValue]]; else if ([token isEqual: @"&&"]) var = [OFNumber numberWithBool: [first boolValue] && [second boolValue]]; else if ([token isEqual: @"||"]) var = [OFNumber numberWithBool: [first boolValue] || [second boolValue]]; else OFEnsure(0); [stack replaceObjectAtIndex: stackSize - 2 withObject: var]; [stack removeLastObject]; } else if (precedence == 1) { stackSize = stack.count; first = stack.lastObject; if ([token isEqual: @"!"]) var = [OFNumber numberWithBool: ![first boolValue]]; else if ([token isEqual: @"is_real"]) var = [OFNumber numberWithBool: ([first doubleValue] != [first longLongValue])]; else OFEnsure(0); [stack replaceObjectAtIndex: stackSize - 1 withObject: var]; } else [stack addObject: token]; } |
︙ | ︙ | |||
351 352 353 354 355 356 357 | } + (OFString *)territory { return currentLocale.territory; } | | | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | } + (OFString *)territory { return currentLocale.territory; } + (OFStringEncoding)encoding { return currentLocale.encoding; } + (OFString *)decimalPoint { return currentLocale.decimalPoint; |
︙ | ︙ | |||
380 381 382 383 384 385 386 | #ifndef OF_AMIGAOS char *locale, *messagesLocale = NULL; if (currentLocale != nil) @throw [OFInitializationFailedException exceptionWithClass: self.class]; | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | #ifndef OF_AMIGAOS char *locale, *messagesLocale = NULL; if (currentLocale != nil) @throw [OFInitializationFailedException exceptionWithClass: self.class]; _encoding = OFStringEncodingUTF8; _decimalPoint = @"."; _localizedStrings = [[OFMutableArray alloc] init]; if ((locale = setlocale(LC_ALL, "")) != NULL) _decimalPoint = [[OFString alloc] initWithCString: localeconv()->decimal_point encoding: _encoding]; |
︙ | ︙ | |||
424 425 426 427 428 429 430 | # if defined(OF_MORPHOS) if (GetVar("CODEPAGE", buffer, sizeof(buffer), 0) > 0) { # elif defined(OF_AMIGAOS4) if (GetVar("Charset", buffer, sizeof(buffer), 0) > 0) { # else if (0) { # endif | | | | | | 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | # if defined(OF_MORPHOS) if (GetVar("CODEPAGE", buffer, sizeof(buffer), 0) > 0) { # elif defined(OF_AMIGAOS4) if (GetVar("Charset", buffer, sizeof(buffer), 0) > 0) { # else if (0) { # endif OFStringEncoding ASCII = OFStringEncodingASCII; @try { _encoding = OFStringEncodingParseName( [OFString stringWithCString: buffer encoding: ASCII]); } @catch (OFInvalidArgumentException *e) { _encoding = OFStringEncodingISO8859_1; } } else _encoding = OFStringEncodingISO8859_1; /* * Get it via localeconv() instead of from the Locale struct, * to make sure we and printf etc. have the same expectations. */ _decimalPoint = [[OFString alloc] initWithCString: localeconv()->decimal_point |
︙ | ︙ | |||
457 458 459 460 461 462 463 | if ((locale = OpenLocale(NULL)) != NULL) { @try { uint32_t territory; size_t length; territory = | | | 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | if ((locale = OpenLocale(NULL)) != NULL) { @try { uint32_t territory; size_t length; territory = OFToBigEndian32(locale->loc_CountryCode); for (length = 0; length < 4; length++) if (((char *)&territory)[length] == 0) break; _territory = [[OFString alloc] initWithCString: (char *)&territory |
︙ | ︙ | |||
569 570 571 572 573 574 575 | OFConstantString *name; const char *UTF8String = NULL; size_t last, UTF8StringLength; int state = 0; variables = [OFMutableDictionary dictionary]; while ((name = va_arg(arguments, OFConstantString *)) != nil) | | < | 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 | OFConstantString *name; const char *UTF8String = NULL; size_t last, UTF8StringLength; int state = 0; variables = [OFMutableDictionary dictionary]; while ((name = va_arg(arguments, OFConstantString *)) != nil) [variables setObject: va_arg(arguments, id) forKey: name]; for (OFDictionary *strings in _localizedStrings) { id string = [strings objectForKey: ID]; if (string == nil) continue; |
︙ | ︙ |
Modified src/OFLocking.h from [9eac423122] to [ae2e49ea45].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMD5Hash.h from [115122e9c6] to [cdd5a3515e].
1 | /* | < < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFCryptographicHash.h" OF_ASSUME_NONNULL_BEGIN @class OFSecureData; /** * @class OFMD5Hash OFMD5Hash.h ObjFW/OFMD5Hash.h * * @brief A class which provides methods to create an MD5 hash. */ OF_SUBCLASSING_RESTRICTED @interface OFMD5Hash: OFObject <OFCryptographicHash> { OFSecureData *_iVarsData; struct { uint32_t state[4]; uint64_t bits; union { unsigned char bytes[64]; uint32_t words[16]; } buffer; size_t bufferLength; } *_iVars; bool _allowsSwappableMemory; bool _calculated; } @end OF_ASSUME_NONNULL_END |
Modified src/OFMD5Hash.m from [f7acc8c4b8] to [190d96fa7c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 | #include <string.h> #import "OFMD5Hash.h" #import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFOutOfRangeException.h" | > < | > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <string.h> #import "OFMD5Hash.h" #import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFHashNotCalculatedException.h" #import "OFOutOfRangeException.h" static const size_t digestSize = 16; static const size_t blockSize = 64; OF_DIRECT_MEMBERS @interface OFMD5Hash () - (void)of_resetState; @end #define F(a, b, c) (((a) & (b)) | (~(a) & (c))) |
︙ | ︙ | |||
73 74 75 76 77 78 79 | }; static OF_INLINE void byteSwapVectorIfBE(uint32_t *vector, uint_fast8_t length) { #ifdef OF_BIG_ENDIAN for (uint_fast8_t i = 0; i < length; i++) | | | | | | | | | | > | | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | }; static OF_INLINE void byteSwapVectorIfBE(uint32_t *vector, uint_fast8_t length) { #ifdef OF_BIG_ENDIAN for (uint_fast8_t i = 0; i < length; i++) vector[i] = OFByteSwap32(vector[i]); #endif } static void processBlock(uint32_t *state, uint32_t *buffer) { uint32_t new[4]; uint_fast8_t i = 0; new[0] = state[0]; new[1] = state[1]; new[2] = state[2]; new[3] = state[3]; byteSwapVectorIfBE(buffer, 16); #define LOOP_BODY(f) \ { \ uint32_t tmp = new[3]; \ tmp = new[3]; \ new[0] += f(new[1], new[2], new[3]) + \ buffer[wordOrder[i]] + table[i]; \ new[3] = new[2]; \ new[2] = new[1]; \ new[1] += OFRotateLeft(new[0], \ rotateBits[(i % 4) + (i / 16) * 4]); \ new[0] = tmp; \ } for (; i < 16; i++) LOOP_BODY(F) for (; i < 32; i++) LOOP_BODY(G) for (; i < 48; i++) |
︙ | ︙ | |||
125 126 127 128 129 130 131 | @implementation OFMD5Hash @synthesize calculated = _calculated; @synthesize allowsSwappableMemory = _allowsSwappableMemory; + (size_t)digestSize { | | | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | @implementation OFMD5Hash @synthesize calculated = _calculated; @synthesize allowsSwappableMemory = _allowsSwappableMemory; + (size_t)digestSize { return digestSize; } + (size_t)blockSize { return blockSize; } + (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory { return [[[self alloc] initWithAllowsSwappableMemory: allowsSwappableMemory] autorelease]; } - (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory { |
︙ | ︙ | |||
178 179 180 181 182 183 184 | [_iVarsData release]; [super dealloc]; } - (size_t)digestSize { | | | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | [_iVarsData release]; [super dealloc]; } - (size_t)digestSize { return digestSize; } - (size_t)blockSize { return blockSize; } - (id)copy { OFMD5Hash *copy = [[OFMD5Hash alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; |
︙ | ︙ | |||
206 207 208 209 210 211 212 | { _iVars->state[0] = 0x67452301; _iVars->state[1] = 0xEFCDAB89; _iVars->state[2] = 0x98BADCFE; _iVars->state[3] = 0x10325476; } | | < | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | { _iVars->state[0] = 0x67452301; _iVars->state[1] = 0xEFCDAB89; _iVars->state[2] = 0x98BADCFE; _iVars->state[3] = 0x10325476; } - (void)updateWithBuffer: (const void *)buffer_ length: (size_t)length { const unsigned char *buffer = buffer_; if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; |
︙ | ︙ | |||
242 243 244 245 246 247 248 | _iVars->bufferLength = 0; } } } - (const unsigned char *)digest { | | > > | | > > > > > > > | | | | | < < | | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | _iVars->bufferLength = 0; } } } - (const unsigned char *)digest { if (!_calculated) @throw [OFHashNotCalculatedException exceptionWithObject: self]; return (const unsigned char *)_iVars->state; } - (void)calculate { if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; _iVars->buffer.bytes[_iVars->bufferLength] = 0x80; OFZeroMemory(_iVars->buffer.bytes + _iVars->bufferLength + 1, 64 - _iVars->bufferLength - 1); if (_iVars->bufferLength >= 56) { processBlock(_iVars->state, _iVars->buffer.words); OFZeroMemory(_iVars->buffer.bytes, 64); } _iVars->buffer.words[14] = OFToLittleEndian32((uint32_t)(_iVars->bits & 0xFFFFFFFF)); _iVars->buffer.words[15] = OFToLittleEndian32((uint32_t)(_iVars->bits >> 32)); processBlock(_iVars->state, _iVars->buffer.words); OFZeroMemory(&_iVars->buffer, sizeof(_iVars->buffer)); byteSwapVectorIfBE(_iVars->state, 4); _calculated = true; } - (void)reset { [self of_resetState]; _iVars->bits = 0; OFZeroMemory(&_iVars->buffer, sizeof(_iVars->buffer)); _iVars->bufferLength = 0; _calculated = false; } @end |
Modified src/OFMapTable+Private.h from [1364bfeb16] to [34b0bddd51].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMapTable.h from [bf028bd496] to [db5052bd42].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | #import "OFEnumerator.h" OF_ASSUME_NONNULL_BEGIN /** @file */ /** | | | < | | | | | | | | | < | | < | | | | | | < | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | #import "OFEnumerator.h" OF_ASSUME_NONNULL_BEGIN /** @file */ /** * @struct OFMapTableFunctions OFMapTable.h ObjFW/OFMapTable.h * * @brief A struct describing the functions to be used by the map table. */ typedef struct { /** The function to retain keys / objects */ void *_Nullable (*_Nullable retain)(void *_Nullable object); /** The function to release keys / objects */ void (*_Nullable release)(void *_Nullable object); /** The function to hash keys */ unsigned long (*_Nullable hash)(void *_Nullable object); /** The function to compare keys / objects */ bool (*_Nullable equal)(void *_Nullable object1, void *_Nullable object2); } OFMapTableFunctions; #ifdef OF_HAVE_BLOCKS /** * @brief A block for enumerating an OFMapTable. * * @param key The current key * @param object The current object * @param stop A pointer to a variable that can be set to true to stop the * enumeration */ typedef void (^OFMapTableEnumerationBlock)(void *_Nullable key, void *_Nullable object, bool *stop); /** * @brief A block for replacing objects in an OFMapTable. * * @param key The key of the object to replace * @param object The object to replace * @return The object to replace the object with */ typedef void *_Nullable (^OFMapTableReplaceBlock)(void *_Nullable key, void *_Nullable object); #endif @class OFMapTableEnumerator; /** * @class OFMapTable OFMapTable.h ObjFW/OFMapTable.h * * @brief A class similar to OFDictionary, but providing more options how keys * and objects should be retained, released, compared and hashed. */ OF_SUBCLASSING_RESTRICTED @interface OFMapTable: OFObject <OFCopying, OFFastEnumeration> { OFMapTableFunctions _keyFunctions, _objectFunctions; struct OFMapTableBucket *_Nonnull *_Nullable _buckets; uint32_t _count, _capacity; unsigned char _rotate; unsigned long _mutations; } /** * @brief The key functions used by the map table. */ @property (readonly, nonatomic) OFMapTableFunctions keyFunctions; /** * @brief The object functions used by the map table. */ @property (readonly, nonatomic) OFMapTableFunctions objectFunctions; /** * @brief The number of objects in the map table. */ @property (readonly, nonatomic) size_t count; /** * @brief Creates a new OFMapTable with the specified key and object functions. * * @param keyFunctions A structure of functions for handling keys * @param objectFunctions A structure of functions for handling objects * @return A new autoreleased OFMapTable */ + (instancetype)mapTableWithKeyFunctions: (OFMapTableFunctions)keyFunctions objectFunctions: (OFMapTableFunctions)objectFunctions; /** * @brief Creates a new OFMapTable with the specified key functions, object * functions and capacity. * * @param keyFunctions A structure of functions for handling keys * @param objectFunctions A structure of functions for handling objects * @param capacity A hint about the count of elements expected to be in the map * table * @return A new autoreleased OFMapTable */ + (instancetype)mapTableWithKeyFunctions: (OFMapTableFunctions)keyFunctions objectFunctions: (OFMapTableFunctions)objectFunctions capacity: (size_t)capacity; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFMapTable with the specified key * and object functions. * * @param keyFunctions A structure of functions for handling keys * @param objectFunctions A structure of functions for handling objects * @return An initialized OFMapTable */ - (instancetype)initWithKeyFunctions: (OFMapTableFunctions)keyFunctions objectFunctions: (OFMapTableFunctions)objectFunctions; /** * @brief Initializes an already allocated OFMapTable with the specified key * functions, object functions and capacity. * * @param keyFunctions A structure of functions for handling keys * @param objectFunctions A structure of functions for handling objects * @param capacity A hint about the count of elements expected to be in the map * table * @return An initialized OFMapTable */ - (instancetype)initWithKeyFunctions: (OFMapTableFunctions)keyFunctions objectFunctions: (OFMapTableFunctions)objectFunctions capacity: (size_t)capacity OF_DESIGNATED_INITIALIZER; /** * @brief Returns the object for the given key or NULL if the key was not found. * * @param key The key whose object should be returned * @return The object for the given key or NULL if the key was not found */ - (nullable void *)objectForKey: (void *)key; /** * @brief Sets an object for a key. * * @param key The key to set * @param object The object to set the key to */ - (void)setObject: (nullable void *)object forKey: (nullable void *)key; /** * @brief Removes the object for the specified key from the map table. * * @param key The key whose object should be removed */ - (void)removeObjectForKey: (nullable void *)key; |
︙ | ︙ | |||
216 217 218 219 220 221 222 | #ifdef OF_HAVE_BLOCKS /** * @brief Executes a block for each key / object pair. * * @param block The block to execute for each key / object pair. */ | | < | | | | | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | #ifdef OF_HAVE_BLOCKS /** * @brief Executes a block for each key / object pair. * * @param block The block to execute for each key / object pair. */ - (void)enumerateKeysAndObjectsUsingBlock: (OFMapTableEnumerationBlock)block; /** * @brief Replaces each object with the object returned by the block. * * @param block The block which returns a new object for each object */ - (void)replaceObjectsUsingBlock: (OFMapTableReplaceBlock)block; #endif @end /** * @class OFMapTableEnumerator OFMapTable.h ObjFW/OFMapTable.h * * @brief A class which provides methods to enumerate through an OFMapTable's * keys or objects. */ @interface OFMapTableEnumerator: OFObject { OFMapTable *_mapTable; struct OFMapTableBucket *_Nonnull *_Nullable _buckets; uint32_t _capacity; unsigned long _mutations, *_Nullable _mutationsPtr, _position; } - (instancetype)init OF_UNAVAILABLE; /** * @brief Returns a pointer to the next object, or NULL if the enumeration * finished. |
︙ | ︙ |
Modified src/OFMapTable.m from [8775708778] to [155910f8b1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
26 27 28 29 30 31 32 | #import "OFMapTable+Private.h" #import "OFEnumerator.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" | > | > | | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #import "OFMapTable+Private.h" #import "OFEnumerator.h" #import "OFEnumerationMutationException.h" #import "OFInvalidArgumentException.h" #import "OFOutOfRangeException.h" extern uint32_t OFHashSeed; static const uint32_t minCapacity = 16; struct OFMapTableBucket { void *key, *object; uint32_t hash; }; static struct OFMapTableBucket deletedBucket = { 0 }; static void * defaultRetain(void *object) { return object; } |
︙ | ︙ | |||
57 58 59 60 61 62 63 | static bool defaultEqual(void *object1, void *object2) { return (object1 == object2); } | < < < < < < < | | | < | | < | | | | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | static bool defaultEqual(void *object1, void *object2) { return (object1 == object2); } OF_DIRECT_MEMBERS @interface OFMapTableEnumerator () - (instancetype)of_initWithMapTable: (OFMapTable *)mapTable buckets: (struct OFMapTableBucket **)buckets capacity: (uint32_t)capacity mutationsPointer: (unsigned long *)mutationsPtr OF_METHOD_FAMILY(init); @end @interface OFMapTableKeyEnumerator: OFMapTableEnumerator @end @interface OFMapTableObjectEnumerator: OFMapTableEnumerator @end @implementation OFMapTable @synthesize keyFunctions = _keyFunctions, objectFunctions = _objectFunctions; + (instancetype)mapTableWithKeyFunctions: (OFMapTableFunctions)keyFunctions objectFunctions: (OFMapTableFunctions)objectFunctions { return [[[self alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions] autorelease]; } + (instancetype)mapTableWithKeyFunctions: (OFMapTableFunctions)keyFunctions objectFunctions: (OFMapTableFunctions)objectFunctions capacity: (size_t)capacity { return [[[self alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions capacity: capacity] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithKeyFunctions: (OFMapTableFunctions)keyFunctions objectFunctions: (OFMapTableFunctions)objectFunctions { return [self initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions capacity: 0]; } - (instancetype)initWithKeyFunctions: (OFMapTableFunctions)keyFunctions objectFunctions: (OFMapTableFunctions)objectFunctions capacity: (size_t)capacity { self = [super init]; @try { _keyFunctions = keyFunctions; _objectFunctions = objectFunctions; |
︙ | ︙ | |||
141 142 143 144 145 146 147 | SET_DEFAULT(_objectFunctions.retain, defaultRetain); SET_DEFAULT(_objectFunctions.release, defaultRelease); SET_DEFAULT(_objectFunctions.hash, defaultHash); SET_DEFAULT(_objectFunctions.equal, defaultEqual); #undef SET_DEFAULT | | | | | | | | < | | | | | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < | | | | | | | | | | | | | | | < | < | | | | | | | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | SET_DEFAULT(_objectFunctions.retain, defaultRetain); SET_DEFAULT(_objectFunctions.release, defaultRelease); SET_DEFAULT(_objectFunctions.hash, defaultHash); SET_DEFAULT(_objectFunctions.equal, defaultEqual); #undef SET_DEFAULT if (capacity > UINT32_MAX / sizeof(*_buckets) || capacity > UINT32_MAX / 8) @throw [OFOutOfRangeException exception]; for (_capacity = 1; _capacity < capacity;) { if (_capacity > UINT32_MAX / 2) @throw [OFOutOfRangeException exception]; _capacity *= 2; } if (capacity * 8 / _capacity >= 6) if (_capacity <= UINT32_MAX / 2) _capacity *= 2; if (_capacity < minCapacity) _capacity = minCapacity; _buckets = OFAllocZeroedMemory(_capacity, sizeof(*_buckets)); if (OFHashSeed != 0) _rotate = OFRandom16() & 31; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { for (uint32_t i = 0; i < _capacity; i++) { if (_buckets[i] != NULL && _buckets[i] != &deletedBucket) { _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); OFFreeMemory(_buckets[i]); } } OFFreeMemory(_buckets); [super dealloc]; } static void resizeForCount(OFMapTable *self, uint32_t count) { uint32_t fullness, capacity; struct OFMapTableBucket **buckets; if (count > UINT32_MAX / sizeof(*self->_buckets) || count > UINT32_MAX / 8) @throw [OFOutOfRangeException exception]; fullness = count * 8 / self->_capacity; if (fullness >= 6) { if (self->_capacity > UINT32_MAX / 2) return; capacity = self->_capacity * 2; } else if (fullness <= 1) capacity = self->_capacity / 2; else return; /* * Don't downsize if we have an initial capacity or if we would fall * below the minimum capacity. */ if ((capacity < self->_capacity && count > self->_count) || capacity < minCapacity) return; buckets = OFAllocZeroedMemory(capacity, sizeof(*buckets)); for (uint32_t i = 0; i < self->_capacity; i++) { if (self->_buckets[i] != NULL && self->_buckets[i] != &deletedBucket) { uint32_t j, last; last = capacity; for (j = self->_buckets[i]->hash & (capacity - 1); j < last && buckets[j] != NULL; j++); /* In case the last bucket is already used */ if (j >= last) { last = self->_buckets[i]->hash & (capacity - 1); for (j = 0; j < last && buckets[j] != NULL; j++); } if (j >= last) @throw [OFOutOfRangeException exception]; buckets[j] = self->_buckets[i]; } } OFFreeMemory(self->_buckets); self->_buckets = buckets; self->_capacity = capacity; } static void setObject(OFMapTable *restrict self, void *key, void *object, uint32_t hash) { uint32_t i, last; void *old; if (key == NULL || object == NULL) @throw [OFInvalidArgumentException exception]; hash = OFRotateLeft(hash, self->_rotate); last = self->_capacity; for (i = hash & (self->_capacity - 1); i < last && self->_buckets[i] != NULL; i++) { if (self->_buckets[i] == &deletedBucket) continue; if (self->_keyFunctions.equal(self->_buckets[i]->key, key)) break; } /* In case the last bucket is already used */ if (i >= last) { last = hash & (self->_capacity - 1); for (i = 0; i < last && self->_buckets[i] != NULL; i++) { if (self->_buckets[i] == &deletedBucket) continue; if (self->_keyFunctions.equal( self->_buckets[i]->key, key)) break; } } /* Key not in map table */ if (i >= last || self->_buckets[i] == NULL || self->_buckets[i] == &deletedBucket || !self->_keyFunctions.equal(self->_buckets[i]->key, key)) { struct OFMapTableBucket *bucket; resizeForCount(self, self->_count + 1); self->_mutations++; last = self->_capacity; for (i = hash & (self->_capacity - 1); i < last && self->_buckets[i] != NULL && self->_buckets[i] != &deletedBucket; i++); /* In case the last bucket is already used */ if (i >= last) { last = hash & (self->_capacity - 1); for (i = 0; i < last && self->_buckets[i] != NULL && self->_buckets[i] != &deletedBucket; i++); } if (i >= last) @throw [OFOutOfRangeException exception]; bucket = OFAllocMemory(1, sizeof(*bucket)); @try { bucket->key = self->_keyFunctions.retain(key); } @catch (id e) { OFFreeMemory(bucket); @throw e; } @try { bucket->object = self->_objectFunctions.retain(object); } @catch (id e) { self->_keyFunctions.release(bucket->key); OFFreeMemory(bucket); @throw e; } bucket->hash = hash; self->_buckets[i] = bucket; self->_count++; return; } old = self->_buckets[i]->object; self->_buckets[i]->object = self->_objectFunctions.retain(object); self->_objectFunctions.release(old); } - (bool)isEqual: (id)object { OFMapTable *mapTable; if (object == self) return true; if (![object isKindOfClass: [OFMapTable class]]) return false; mapTable = object; if (mapTable->_count != _count || mapTable->_keyFunctions.equal != _keyFunctions.equal || mapTable->_objectFunctions.equal != _objectFunctions.equal) return false; for (uint32_t i = 0; i < _capacity; i++) { if (_buckets[i] != NULL && _buckets[i] != &deletedBucket) { void *objectIter = [mapTable objectForKey: _buckets[i]->key]; if (!_objectFunctions.equal(objectIter, _buckets[i]->object)) return false; } } return true; } - (unsigned long)hash { unsigned long hash = 0; for (unsigned long i = 0; i < _capacity; i++) { if (_buckets[i] != NULL && _buckets[i] != &deletedBucket) { hash ^= OFRotateRight(_buckets[i]->hash, _rotate); hash ^= _objectFunctions.hash(_buckets[i]->object); } } return hash; } - (id)copy { OFMapTable *copy = [[OFMapTable alloc] initWithKeyFunctions: _keyFunctions objectFunctions: _objectFunctions capacity: _capacity]; @try { for (uint32_t i = 0; i < _capacity; i++) if (_buckets[i] != NULL && _buckets[i] != &deletedBucket) setObject(copy, _buckets[i]->key, _buckets[i]->object, OFRotateRight(_buckets[i]->hash, _rotate)); } @catch (id e) { [copy release]; @throw e; } return copy; } - (size_t)count { return _count; } - (void *)objectForKey: (void *)key { uint32_t i, hash, last; if (key == NULL) @throw [OFInvalidArgumentException exception]; hash = OFRotateLeft((uint32_t)_keyFunctions.hash(key), _rotate); last = _capacity; for (i = hash & (_capacity - 1); i < last && _buckets[i] != NULL; i++) { if (_buckets[i] == &deletedBucket) continue; if (_keyFunctions.equal(_buckets[i]->key, key)) return _buckets[i]->object; } if (i < last) return nil; /* In case the last bucket is already used */ last = hash & (_capacity - 1); for (i = 0; i < last && _buckets[i] != NULL; i++) { if (_buckets[i] == &deletedBucket) continue; if (_keyFunctions.equal(_buckets[i]->key, key)) return _buckets[i]->object; } return NULL; } - (void)setObject: (void *)object forKey: (void *)key { setObject(self, key, object, (uint32_t)_keyFunctions.hash(key)); } - (void)removeObjectForKey: (void *)key { uint32_t i, hash, last; if (key == NULL) @throw [OFInvalidArgumentException exception]; hash = OFRotateLeft((uint32_t)_keyFunctions.hash(key), _rotate); last = _capacity; for (i = hash & (_capacity - 1); i < last && _buckets[i] != NULL; i++) { if (_buckets[i] == &deletedBucket) continue; if (_keyFunctions.equal(_buckets[i]->key, key)) { _mutations++; _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); OFFreeMemory(_buckets[i]); _buckets[i] = &deletedBucket; _count--; resizeForCount(self, _count); return; } } if (i < last) return; /* In case the last bucket is already used */ last = hash & (_capacity - 1); for (i = 0; i < last && _buckets[i] != NULL; i++) { if (_buckets[i] == &deletedBucket) continue; if (_keyFunctions.equal(_buckets[i]->key, key)) { _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); OFFreeMemory(_buckets[i]); _buckets[i] = &deletedBucket; _count--; _mutations++; resizeForCount(self, _count); return; } } } - (void)removeAllObjects { for (uint32_t i = 0; i < _capacity; i++) { if (_buckets[i] != NULL) { if (_buckets[i] == &deletedBucket) { _buckets[i] = NULL; continue; } _keyFunctions.release(_buckets[i]->key); _objectFunctions.release(_buckets[i]->object); OFFreeMemory(_buckets[i]); _buckets[i] = NULL; } } _count = 0; _capacity = minCapacity; _buckets = OFResizeMemory(_buckets, _capacity, sizeof(*_buckets)); /* * Get a new random value for _rotate, so that it is not less secure * than creating a new hash map. */ if (OFHashSeed != 0) _rotate = OFRandom16() & 31; } - (bool)containsObject: (void *)object { if (object == NULL || _count == 0) return false; for (uint32_t i = 0; i < _capacity; i++) if (_buckets[i] != NULL && _buckets[i] != &deletedBucket) if (_objectFunctions.equal(_buckets[i]->object, object)) return true; return false; } - (bool)containsObjectIdenticalTo: (void *)object { if (object == NULL || _count == 0) return false; for (uint32_t i = 0; i < _capacity; i++) if (_buckets[i] != NULL && _buckets[i] != &deletedBucket) if (_buckets[i]->object == object) return true; return false; } - (OFMapTableEnumerator *)keyEnumerator |
︙ | ︙ | |||
577 578 579 580 581 582 583 | return [[[OFMapTableObjectEnumerator alloc] of_initWithMapTable: self buckets: _buckets capacity: _capacity mutationsPointer: &_mutations] autorelease]; } | | | | < | | | | 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | return [[[OFMapTableObjectEnumerator alloc] of_initWithMapTable: self buckets: _buckets capacity: _capacity mutationsPointer: &_mutations] autorelease]; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { unsigned long j = state->state; int i; for (i = 0; i < count; i++) { for (; j < _capacity && (_buckets[j] == NULL || _buckets[j] == &deletedBucket); j++); if (j < _capacity) { objects[i] = _buckets[j]->key; j++; } else break; } state->state = j; state->itemsPtr = objects; state->mutationsPtr = &_mutations; return i; } #ifdef OF_HAVE_BLOCKS - (void)enumerateKeysAndObjectsUsingBlock: (OFMapTableEnumerationBlock)block { bool stop = false; unsigned long mutations = _mutations; for (size_t i = 0; i < _capacity && !stop; i++) { if (_mutations != mutations) @throw [OFEnumerationMutationException exceptionWithObject: self]; if (_buckets[i] != NULL && _buckets[i] != &deletedBucket) block(_buckets[i]->key, _buckets[i]->object, &stop); } } - (void)replaceObjectsUsingBlock: (OFMapTableReplaceBlock)block { unsigned long mutations = _mutations; for (size_t i = 0; i < _capacity; i++) { if (_mutations != mutations) @throw [OFEnumerationMutationException exceptionWithObject: self]; if (_buckets[i] != NULL && _buckets[i] != &deletedBucket) { void *new; new = block(_buckets[i]->key, _buckets[i]->object); if (new == NULL) @throw [OFInvalidArgumentException exception]; if (new != _buckets[i]->object) { |
︙ | ︙ | |||
653 654 655 656 657 658 659 | @implementation OFMapTableEnumerator - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)of_initWithMapTable: (OFMapTable *)mapTable | | | | 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 | @implementation OFMapTableEnumerator - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)of_initWithMapTable: (OFMapTable *)mapTable buckets: (struct OFMapTableBucket **)buckets capacity: (uint32_t)capacity mutationsPointer: (unsigned long *)mutationsPtr { self = [super init]; _mapTable = [mapTable retain]; _buckets = buckets; _capacity = capacity; |
︙ | ︙ | |||
689 690 691 692 693 694 695 | - (void **)nextObject { if (*_mutationsPtr != _mutations) @throw [OFEnumerationMutationException exceptionWithObject: _mapTable]; for (; _position < _capacity && (_buckets[_position] == NULL || | | | | 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 | - (void **)nextObject { if (*_mutationsPtr != _mutations) @throw [OFEnumerationMutationException exceptionWithObject: _mapTable]; for (; _position < _capacity && (_buckets[_position] == NULL || _buckets[_position] == &deletedBucket); _position++); if (_position < _capacity) return &_buckets[_position++]->key; else return NULL; } @end @implementation OFMapTableObjectEnumerator - (void **)nextObject { if (*_mutationsPtr != _mutations) @throw [OFEnumerationMutationException exceptionWithObject: _mapTable]; for (; _position < _capacity && (_buckets[_position] == NULL || _buckets[_position] == &deletedBucket); _position++); if (_position < _capacity) return &_buckets[_position++]->object; else return NULL; } @end |
︙ | ︙ |
Modified src/OFMapTableDictionary.h from [bf16e6f63c] to [23bbcf2cb0].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMapTableDictionary.m from [d2c4c5ea8c] to [3e7005d616].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
57 58 59 60 61 62 63 | static bool equal(void *object1, void *object2) { return [(id)object1 isEqual: (id)object2]; } | | | | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | static bool equal(void *object1, void *object2) { return [(id)object1 isEqual: (id)object2]; } static const OFMapTableFunctions keyFunctions = { .retain = copy, .release = release, .hash = hash, .equal = equal }; static const OFMapTableFunctions objectFunctions = { .retain = retain, .release = release, .hash = hash, .equal = equal }; @implementation OFMapTableDictionary |
︙ | ︙ | |||
135 136 137 138 139 140 141 | OFEnumerator *keyEnumerator, *objectEnumerator; id key, object; keyEnumerator = [dictionary keyEnumerator]; objectEnumerator = [dictionary objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) | | < | < | < | < | < | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | OFEnumerator *keyEnumerator, *objectEnumerator; id key, object; keyEnumerator = [dictionary keyEnumerator]; objectEnumerator = [dictionary objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) [_mapTable setObject: object forKey: key]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObject: (id)object forKey: (id)key { self = [self initWithCapacity: 1]; @try { [_mapTable setObject: object forKey: key]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObjects: (id const *)objects forKeys: (id const *)keys count: (size_t)count { self = [self initWithCapacity: count]; @try { size_t i; for (i = 0; i < count; i++) [_mapTable setObject: objects[i] forKey: keys[i]]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithKey: (id)firstKey arguments: (va_list)arguments { self = [super init]; @try { va_list argumentsCopy; id key, object; size_t i, count; |
︙ | ︙ | |||
216 217 218 219 220 221 222 | count /= 2; _mapTable = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions capacity: count]; | | < | < | | | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | count /= 2; _mapTable = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions capacity: count]; [_mapTable setObject: object forKey: key]; for (i = 1; i < count; i++) { key = va_arg(arguments, id); object = va_arg(arguments, id); if (key == nil || object == nil) @throw [OFInvalidArgumentException exception]; [_mapTable setObject: object forKey: key]; } } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFArray *keys, *objects; OFEnumerator *keyEnumerator, *objectEnumerator; OFXMLElement *keyElement, *objectElement; keys = [element elementsForName: @"key" namespace: OFSerializationNS]; objects = [element elementsForName: @"object" namespace: OFSerializationNS]; if (keys.count != objects.count) @throw [OFInvalidFormatException exception]; _mapTable = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions capacity: keys.count]; keyEnumerator = [keys objectEnumerator]; objectEnumerator = [objects objectEnumerator]; while ((keyElement = [keyEnumerator nextObject]) != nil && (objectElement = [objectEnumerator nextObject]) != nil) { void *pool2 = objc_autoreleasePoolPush(); OFXMLElement *key, *object; key = [keyElement elementsForNamespace: OFSerializationNS].firstObject; object = [objectElement elementsForNamespace: OFSerializationNS].firstObject; if (key == nil || object == nil) @throw [OFInvalidFormatException exception]; [_mapTable setObject: object.objectByDeserializing forKey: key.objectByDeserializing]; |
︙ | ︙ | |||
340 341 342 343 344 345 346 | - (OFArray *)allKeys { OFArray *ret; id *keys; size_t count; count = _mapTable.count; | | < | < | | < | < | | | < | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | - (OFArray *)allKeys { OFArray *ret; id *keys; size_t count; count = _mapTable.count; keys = OFAllocMemory(count, sizeof(*keys)); @try { void *pool = objc_autoreleasePoolPush(); OFMapTableEnumerator *enumerator; void **keyPtr; size_t i; i = 0; enumerator = [_mapTable keyEnumerator]; while ((keyPtr = [enumerator nextObject]) != NULL) { assert(i < count); keys[i++] = (id)*keyPtr; } objc_autoreleasePoolPop(pool); ret = [OFArray arrayWithObjects: keys count: count]; } @finally { OFFreeMemory(keys); } return ret; } - (OFArray *)allObjects { OFArray *ret; id *objects; size_t count; count = _mapTable.count; objects = OFAllocMemory(count, sizeof(*objects)); @try { void *pool = objc_autoreleasePoolPush(); OFMapTableEnumerator *enumerator; void **objectPtr; size_t i; i = 0; enumerator = [_mapTable objectEnumerator]; while ((objectPtr = [enumerator nextObject]) != NULL) { assert(i < count); objects[i++] = (id)*objectPtr; } objc_autoreleasePoolPop(pool); ret = [OFArray arrayWithObjects: objects count: count]; } @finally { OFFreeMemory(objects); } return ret; } - (OFEnumerator *)keyEnumerator { return [[[OFMapTableEnumeratorWrapper alloc] initWithEnumerator: [_mapTable keyEnumerator] object: self] autorelease]; } - (OFEnumerator *)objectEnumerator { return [[[OFMapTableEnumeratorWrapper alloc] initWithEnumerator: [_mapTable objectEnumerator] object: self] autorelease]; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { return [_mapTable countByEnumeratingWithState: state objects: objects count: count]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateKeysAndObjectsUsingBlock: (OFDictionaryEnumerationBlock)block { @try { [_mapTable enumerateKeysAndObjectsUsingBlock: ^ (void *key, void *object, bool *stop) { block(key, object, stop); }]; } @catch (OFEnumerationMutationException *e) { |
︙ | ︙ |
Modified src/OFMapTableSet.h from [3804b5f67f] to [1664d9d036].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMapTableSet.m from [6da1f132a2] to [87bc750df2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
49 50 51 52 53 54 55 | static bool equal(void *object1, void *object2) { return [(id)object1 isEqual: (id)object2]; } | | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | static bool equal(void *object1, void *object2) { return [(id)object1 isEqual: (id)object2]; } static const OFMapTableFunctions keyFunctions = { .retain = retain, .release = release, .hash = hash, .equal = equal }; static const OFMapTableFunctions objectFunctions = { NULL }; @implementation OFMapTableSet - (instancetype)init { return [self initWithCapacity: 0]; } |
︙ | ︙ | |||
98 99 100 101 102 103 104 | @throw e; } self = [self initWithCapacity: count]; @try { for (id object in set) | | < | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | @throw e; } self = [self initWithCapacity: count]; @try { for (id object in set) [_mapTable setObject: (void *)1 forKey: object]; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
126 127 128 129 130 131 132 | @throw e; } self = [self initWithCapacity: count]; @try { for (id object in array) | | < | < | < | < | < | < | | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | @throw e; } self = [self initWithCapacity: count]; @try { for (id object in array) [_mapTable setObject: (void *)1 forKey: object]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { self = [self initWithCapacity: count]; @try { for (size_t i = 0; i < count; i++) [_mapTable setObject: (void *)1 forKey: objects[i]]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { self = [super init]; @try { id object; va_list argumentsCopy; size_t count; va_copy(argumentsCopy, arguments); for (count = 1; va_arg(argumentsCopy, id) != nil; count++); _mapTable = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions capacity: count]; [_mapTable setObject: (void *)1 forKey: firstObject]; while ((object = va_arg(arguments, id)) != nil) [_mapTable setObject: (void *)1 forKey: object]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [self init]; @try { void *pool = objc_autoreleasePoolPush(); if ((![element.name isEqual: @"OFSet"] && ![element.name isEqual: @"OFMutableSet"]) || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; for (OFXMLElement *child in [element elementsForNamespace: OFSerializationNS]) { void *pool2 = objc_autoreleasePoolPush(); [_mapTable setObject: (void *)1 forKey: [child objectByDeserializing]]; objc_autoreleasePoolPop(pool2); } |
︙ | ︙ | |||
281 282 283 284 285 286 287 | - (OFEnumerator *)objectEnumerator { return [[[OFMapTableEnumeratorWrapper alloc] initWithEnumerator: [_mapTable keyEnumerator] object: self] autorelease]; } | | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | - (OFEnumerator *)objectEnumerator { return [[[OFMapTableEnumeratorWrapper alloc] initWithEnumerator: [_mapTable keyEnumerator] object: self] autorelease]; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { return [_mapTable countByEnumeratingWithState: state objects: objects count: count]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (OFSetEnumerationBlock)block { @try { [_mapTable enumerateKeysAndObjectsUsingBlock: ^ (void *key, void *object, bool *stop) { block(key, stop); }]; } @catch (OFEnumerationMutationException *e) { @throw [OFEnumerationMutationException exceptionWithObject: self]; } } #endif @end |
Modified src/OFMessagePackExtension.h from [d7cac48dd4] to [45f0ba641f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
50 51 52 53 54 55 56 | * @brief Creates a new OFMessagePackRepresentation with the specified type and * data. * * @param type The MessagePack extension type * @param data The data for the extension * @return A new, autoreleased OFMessagePackRepresentation */ | | < | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | * @brief Creates a new OFMessagePackRepresentation with the specified type and * data. * * @param type The MessagePack extension type * @param data The data for the extension * @return A new, autoreleased OFMessagePackRepresentation */ + (instancetype)extensionWithType: (int8_t)type data: (OFData *)data; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFMessagePackRepresentation with the * specified type and data. * |
︙ | ︙ |
Modified src/OFMessagePackExtension.m from [0041614de1] to [7009717fd9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | #import "OFString.h" #import "OFInvalidArgumentException.h" @implementation OFMessagePackExtension @synthesize type = _type, data = _data; | | < | < | < | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #import "OFString.h" #import "OFInvalidArgumentException.h" @implementation OFMessagePackExtension @synthesize type = _type, data = _data; + (instancetype)extensionWithType: (int8_t)type data: (OFData *)data { return [[[self alloc] initWithType: type data: data] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithType: (int8_t)type data: (OFData *)data { self = [super init]; @try { if (data == nil || data.itemSize != 1) @throw [OFInvalidArgumentException exception]; |
︙ | ︙ | |||
121 122 123 124 125 126 127 | uint16_t length; ret = [OFMutableData dataWithCapacity: count + 4]; prefix = 0xC8; [ret addItem: &prefix]; | | | < | | < | < < | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | uint16_t length; ret = [OFMutableData dataWithCapacity: count + 4]; prefix = 0xC8; [ret addItem: &prefix]; length = OFToBigEndian16((uint16_t)count); [ret addItems: &length count: 2]; [ret addItem: &_type]; } else { uint32_t length; ret = [OFMutableData dataWithCapacity: count + 6]; prefix = 0xC9; [ret addItem: &prefix]; length = OFToBigEndian32((uint32_t)count); [ret addItems: &length count: 4]; [ret addItem: &_type]; } [ret addItems: _data.items count: _data.count]; [ret makeImmutable]; return ret; } - (OFString *)description { |
︙ | ︙ | |||
175 176 177 178 179 180 181 | return false; return true; } - (unsigned long)hash { | | | | | | | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAdd(&hash, (uint8_t)_type); OFHashAddHash(&hash, _data.hash); OFHashFinalize(&hash); return hash; } - (id)copy { return [self retain]; } @end |
Modified src/OFMessagePackRepresentation.h from [6eeb25f988] to [d2e100cc65].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMethodSignature.h from [b2c0b2e4d6] to [6c7eab90df].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
92 93 94 95 96 97 98 | #endif /** * @brief Returns the size for the specified type encoding. * * @param type The type encoding to return the size for * @return The size for the specified type encoding */ | | | | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | #endif /** * @brief Returns the size for the specified type encoding. * * @param type The type encoding to return the size for * @return The size for the specified type encoding */ extern size_t OFSizeOfTypeEncoding(const char *type); /** * @brief Returns the alignment for the specified type encoding. * * @param type The type encoding to return the alignment for * @return The alignment for the specified type encoding */ extern size_t OFAlignmentOfTypeEncoding(const char *type); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFMethodSignature.m from [cf206c5116] to [e6d0a405ec].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "macros.h" | | > | | | | | | | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "macros.h" static size_t alignmentOfEncoding(const char **type, size_t *length, bool inStruct); static size_t sizeOfEncoding(const char **type, size_t *length); static size_t alignmentOfArray(const char **type, size_t *length) { size_t alignment; assert(*length > 0); (*type)++; (*length)--; while (*length > 0 && OFASCIIIsDigit(**type)) { (*type)++; (*length)--; } alignment = alignmentOfEncoding(type, length, true); if (*length == 0 || **type != ']') @throw [OFInvalidFormatException exception]; (*type)++; (*length)--; return alignment; } static size_t alignmentOfStruct(const char **type, size_t *length) { size_t alignment = 0; #if defined(OF_POWERPC) && defined(OF_MACOS) bool first = true; #endif assert(*length > 0); (*type)++; |
︙ | ︙ | |||
81 82 83 84 85 86 87 | @throw [OFInvalidFormatException exception]; /* Skip '=' */ (*type)++; (*length)--; while (*length > 0 && **type != '}') { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 | @throw [OFInvalidFormatException exception]; /* Skip '=' */ (*type)++; (*length)--; while (*length > 0 && **type != '}') { size_t fieldAlignment = alignmentOfEncoding(type, length, true); #if defined(OF_POWERPC) && defined(OF_MACOS) if (!first && fieldAlignment > 4) fieldAlignment = 4; first = false; #endif if (fieldAlignment > alignment) alignment = fieldAlignment; } if (*length == 0 || **type != '}') @throw [OFInvalidFormatException exception]; (*type)++; (*length)--; return alignment; } static size_t alignmentOfUnion(const char **type, size_t *length) { size_t alignment = 0; assert(*length > 0); (*type)++; (*length)--; /* Skip name */ while (*length > 0 && **type != '=') { (*type)++; (*length)--; } if (*length == 0) @throw [OFInvalidFormatException exception]; /* Skip '=' */ (*type)++; (*length)--; while (*length > 0 && **type != ')') { size_t fieldAlignment = alignmentOfEncoding(type, length, true); if (fieldAlignment > alignment) alignment = fieldAlignment; } if (*length == 0 || **type != ')') @throw [OFInvalidFormatException exception]; (*type)++; (*length)--; return alignment; } static size_t alignmentOfEncoding(const char **type, size_t *length, bool inStruct) { size_t alignment; if (*length == 0) @throw [OFInvalidFormatException exception]; if (**type == 'r') { (*type)++; (*length)--; if (*length == 0) @throw [OFInvalidFormatException exception]; } switch (**type) { case 'c': case 'C': alignment = OF_ALIGNOF(char); break; case 'i': case 'I': alignment = OF_ALIGNOF(int); break; case 's': case 'S': alignment = OF_ALIGNOF(short); break; case 'l': case 'L': alignment = OF_ALIGNOF(long); break; case 'q': case 'Q': #if defined(OF_X86) && !defined(OF_WINDOWS) if (inStruct) alignment = 4; else #endif alignment = OF_ALIGNOF(long long); break; #ifdef __SIZEOF_INT128__ case 't': case 'T': alignment = __extension__ OF_ALIGNOF(__int128); break; #endif case 'f': alignment = OF_ALIGNOF(float); break; case 'd': #if defined(OF_X86) && !defined(OF_WINDOWS) if (inStruct) alignment = 4; else #endif alignment = OF_ALIGNOF(double); break; case 'D': #if defined(OF_X86) && !defined(OF_WINDOWS) if (inStruct) alignment = 4; else #endif alignment = OF_ALIGNOF(long double); break; case 'B': alignment = OF_ALIGNOF(_Bool); break; case 'v': alignment = 0; break; case '*': alignment = OF_ALIGNOF(char *); break; case '@': alignment = OF_ALIGNOF(id); break; case '#': alignment = OF_ALIGNOF(Class); break; case ':': alignment = OF_ALIGNOF(SEL); break; case '[': return alignmentOfArray(type, length); case '{': return alignmentOfStruct(type, length); case '(': return alignmentOfUnion(type, length); case '^': /* Just to skip over the rest */ (*type)++; (*length)--; alignmentOfEncoding(type, length, false); return OF_ALIGNOF(void *); #ifndef __STDC_NO_COMPLEX__ case 'j': (*type)++; (*length)--; if (*length == 0) @throw [OFInvalidFormatException exception]; switch (**type) { case 'f': alignment = OF_ALIGNOF(float _Complex); break; case 'd': # if defined(OF_X86) && !defined(OF_WINDOWS) if (inStruct) alignment = 4; else # endif alignment = OF_ALIGNOF(double _Complex); break; case 'D': alignment = OF_ALIGNOF(long double _Complex); break; default: @throw [OFInvalidFormatException exception]; } break; #endif default: @throw [OFInvalidFormatException exception]; } (*type)++; (*length)--; return alignment; } static size_t sizeOfArray(const char **type, size_t *length) { size_t count = 0; size_t size; assert(*length > 0); (*type)++; (*length)--; while (*length > 0 && OFASCIIIsDigit(**type)) { count = count * 10 + **type - '0'; (*type)++; (*length)--; } if (count == 0) @throw [OFInvalidFormatException exception]; size = sizeOfEncoding(type, length); if (*length == 0 || **type != ']') @throw [OFInvalidFormatException exception]; (*type)++; (*length)--; if (SIZE_MAX / count < size) @throw [OFOutOfRangeException exception]; return count * size; } static size_t sizeOfStruct(const char **type, size_t *length) { size_t size = 0; const char *typeCopy = *type; size_t lengthCopy = *length; size_t alignment = alignmentOfStruct(&typeCopy, &lengthCopy); #if defined(OF_POWERPC) && defined(OF_MACOS) bool first = true; #endif assert(*length > 0); (*type)++; |
︙ | ︙ | |||
344 345 346 347 348 349 350 | @throw [OFInvalidFormatException exception]; /* Skip '=' */ (*type)++; (*length)--; while (*length > 0 && **type != '}') { | | | | > | | | | > | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | @throw [OFInvalidFormatException exception]; /* Skip '=' */ (*type)++; (*length)--; while (*length > 0 && **type != '}') { size_t fieldSize, fieldAlignment; typeCopy = *type; lengthCopy = *length; fieldSize = sizeOfEncoding(type, length); fieldAlignment = alignmentOfEncoding(&typeCopy, &lengthCopy, true); #if defined(OF_POWERPC) && defined(OF_MACOS) if (!first && fieldAlignment > 4) fieldAlignment = 4; first = false; #endif if (size % fieldAlignment != 0) { size_t padding = fieldAlignment - (size % fieldAlignment); if (SIZE_MAX - size < padding) @throw [OFOutOfRangeException exception]; size += padding; } |
︙ | ︙ | |||
392 393 394 395 396 397 398 | size += padding; } return size; } static size_t | | | 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | size += padding; } return size; } static size_t sizeOfUnion(const char **type, size_t *length) { size_t size = 0; assert(*length > 0); (*type)++; (*length)--; |
︙ | ︙ | |||
415 416 417 418 419 420 421 | @throw [OFInvalidFormatException exception]; /* Skip '=' */ (*type)++; (*length)--; while (*length > 0 && **type != ')') { | | | | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | @throw [OFInvalidFormatException exception]; /* Skip '=' */ (*type)++; (*length)--; while (*length > 0 && **type != ')') { size_t fieldSize = sizeOfEncoding(type, length); if (fieldSize > size) size = fieldSize; } if (*length == 0 || **type != ')') @throw [OFInvalidFormatException exception]; (*type)++; (*length)--; return size; } static size_t sizeOfEncoding(const char **type, size_t *length) { size_t size; if (*length == 0) @throw [OFInvalidFormatException exception]; if (**type == 'r') { |
︙ | ︙ | |||
501 502 503 504 505 506 507 | case '#': size = sizeof(Class); break; case ':': size = sizeof(SEL); break; case '[': | | | | | | 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | case '#': size = sizeof(Class); break; case ':': size = sizeof(SEL); break; case '[': return sizeOfArray(type, length); case '{': return sizeOfStruct(type, length); case '(': return sizeOfUnion(type, length); case '^': /* Just to skip over the rest */ (*type)++; (*length)--; sizeOfEncoding(type, length); return sizeof(void *); #ifndef __STDC_NO_COMPLEX__ case 'j': (*type)++; (*length)--; |
︙ | ︙ | |||
548 549 550 551 552 553 554 | (*type)++; (*length)--; return size; } size_t | | | | | | 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 | (*type)++; (*length)--; return size; } size_t OFSizeOfTypeEncoding(const char *type) { size_t length = strlen(type); size_t ret = sizeOfEncoding(&type, &length); if (length > 0) @throw [OFInvalidFormatException exception]; return ret; } size_t OFAlignmentOfTypeEncoding(const char *type) { size_t length = strlen(type); size_t ret = alignmentOfEncoding(&type, &length, false); if (length > 0) @throw [OFInvalidFormatException exception]; return ret; } |
︙ | ︙ | |||
593 594 595 596 597 598 599 | @throw [OFInvalidArgumentException exception]; length = strlen(types); if (length == 0) @throw [OFInvalidFormatException exception]; | | | | | 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 | @throw [OFInvalidArgumentException exception]; length = strlen(types); if (length == 0) @throw [OFInvalidFormatException exception]; _types = OFAllocMemory(length + 1, 1); memcpy(_types, types, length); _typesPointers = [[OFMutableData alloc] initWithItemSize: sizeof(char *)]; _offsets = [[OFMutableData alloc] initWithItemSize: sizeof(size_t)]; last = _types; for (size_t i = 0; i < length; i++) { if (OFASCIIIsDigit(_types[i])) { size_t offset = _types[i] - '0'; if (last == _types + i) @throw [OFInvalidFormatException exception]; _types[i] = '\0'; [_typesPointers addItem: &last]; i++; for (; i < length && OFASCIIIsDigit(_types[i]); i++) offset = offset * 10 + _types[i] - '0'; [_offsets addItem: &offset]; last = _types + i; i--; } else if (_types[i] == '{') { |
︙ | ︙ | |||
667 668 669 670 671 672 673 674 675 676 677 678 679 680 | } return self; } - (void)dealloc { [_typesPointers release]; [_offsets release]; [super dealloc]; } - (size_t)numberOfArguments | > | 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 | } return self; } - (void)dealloc { OFFreeMemory(_types); [_typesPointers release]; [_offsets release]; [super dealloc]; } - (size_t)numberOfArguments |
︙ | ︙ |
Modified src/OFMutableAdjacentArray.h from [9d0ea61f45] to [def2b8877c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMutableAdjacentArray.m from [1999b771ee] to [7ff7f8969c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
57 58 59 60 61 62 63 | [_array addItem: &object]; [object retain]; _mutations++; } | | < | < | < | < < | < < < | < | < | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | [_array addItem: &object]; [object retain]; _mutations++; } - (void)insertObject: (id)object atIndex: (size_t)idx { if (object == nil) @throw [OFInvalidArgumentException exception]; @try { [_array insertItem: &object atIndex: idx]; } @catch (OFOutOfRangeException *e) { @throw [OFOutOfRangeException exception]; } [object retain]; _mutations++; } - (void)insertObjectsFromArray: (OFArray *)array atIndex: (size_t)idx { id const *objects = array.objects; size_t count = array.count; @try { [_array insertItems: objects atIndex: idx count: count]; } @catch (OFOutOfRangeException *e) { @throw [OFOutOfRangeException exception]; } for (size_t i = 0; i < count; i++) [objects[i] retain]; _mutations++; } - (void)replaceObject: (id)oldObject withObject: (id)newObject { id *objects; size_t count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; objects = _array.mutableItems; count = _array.count; for (size_t i = 0; i < count; i++) { if ([objects[i] isEqual: oldObject]) { [newObject retain]; [objects[i] release]; objects[i] = newObject; } } } - (void)replaceObjectAtIndex: (size_t)idx withObject: (id)object { id *objects; id oldObject; if (object == nil) @throw [OFInvalidArgumentException exception]; objects = _array.mutableItems; if (idx >= _array.count) @throw [OFOutOfRangeException exception]; oldObject = objects[idx]; objects[idx] = [object retain]; [oldObject release]; } - (void)replaceObjectIdenticalTo: (id)oldObject withObject: (id)newObject { id *objects; size_t count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; |
︙ | ︙ | |||
172 173 174 175 176 177 178 | @throw [OFInvalidArgumentException exception]; objects = _array.items; count = _array.count; for (size_t i = 0; i < count; i++) { if ([objects[i] isEqual: object]) { | | | > > | > | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | @throw [OFInvalidArgumentException exception]; objects = _array.items; count = _array.count; for (size_t i = 0; i < count; i++) { if ([objects[i] isEqual: object]) { id tmp = objects[i]; [_array removeItemAtIndex: i]; _mutations++; [tmp release]; objects = _array.items; i--; count--; continue; } } } - (void)removeObjectIdenticalTo: (id)object { id const *objects; |
︙ | ︙ | |||
202 203 204 205 206 207 208 | for (size_t i = 0; i < count; i++) { if (objects[i] == object) { [_array removeItemAtIndex: i]; _mutations++; [object release]; | > > | > | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | for (size_t i = 0; i < count; i++) { if (objects[i] == object) { [_array removeItemAtIndex: i]; _mutations++; [object release]; objects = _array.items; i--; count--; continue; } } } - (void)removeObjectAtIndex: (size_t)idx { #ifndef __clang_analyzer__ |
︙ | ︙ | |||
229 230 231 232 233 234 235 | for (size_t i = 0; i < count; i++) [objects[i] release]; [_array removeAllItems]; } | | < | | | < | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | for (size_t i = 0; i < count; i++) [objects[i] release]; [_array removeAllItems]; } - (void)removeObjectsInRange: (OFRange)range { id const *objects = _array.items; size_t count = _array.count; id *copy; if (range.length > SIZE_MAX - range.location || range.location >= count || range.length > count - range.location) @throw [OFOutOfRangeException exception]; copy = OFAllocMemory(range.length, sizeof(*copy)); memcpy(copy, objects + range.location, range.length * sizeof(id)); @try { [_array removeItemsInRange: range]; _mutations++; for (size_t i = 0; i < range.length; i++) [copy[i] release]; } @finally { OFFreeMemory(copy); } } - (void)removeLastObject { #ifndef __clang_analyzer__ size_t count = _array.count; id object; if (count == 0) return; object = [self objectAtIndex: count - 1]; [_array removeLastItem]; [object release]; _mutations++; #endif } - (void)exchangeObjectAtIndex: (size_t)idx1 withObjectAtIndex: (size_t)idx2 { id *objects = _array.mutableItems; size_t count = _array.count; id tmp; if (idx1 >= count || idx2 >= count) @throw [OFOutOfRangeException exception]; |
︙ | ︙ | |||
301 302 303 304 305 306 307 | for (i = 0, j = count - 1; i < j; i++, j--) { id tmp = objects[i]; objects[i] = objects[j]; objects[j] = tmp; } } | | | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | for (i = 0, j = count - 1; i < j; i++, j--) { id tmp = objects[i]; objects[i] = objects[j]; objects[j] = tmp; } } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count_ { size_t count = _array.count; if (count > INT_MAX) { /* |
︙ | ︙ | |||
338 339 340 341 342 343 344 | { return [[[OFArrayEnumerator alloc] initWithArray: self mutationsPtr: &_mutations] autorelease]; } #ifdef OF_HAVE_BLOCKS | | | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | { return [[[OFArrayEnumerator alloc] initWithArray: self mutationsPtr: &_mutations] autorelease]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (OFArrayEnumerationBlock)block { id const *objects = _array.items; size_t count = _array.count; bool stop = false; unsigned long mutations = _mutations; for (size_t i = 0; i < count && !stop; i++) { if (_mutations != mutations) @throw [OFEnumerationMutationException exceptionWithObject: self]; block(objects[i], i, &stop); } } - (void)replaceObjectsUsingBlock: (OFArrayReplaceBlock)block { id *objects = _array.mutableItems; size_t count = _array.count; unsigned long mutations = _mutations; for (size_t i = 0; i < count; i++) { id new; |
︙ | ︙ |
Modified src/OFMutableArray.h from [77912a7def] to [43a8133fa8].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | /** * @brief A block for replacing values in an OFMutableArray. * * @param object The object to replace * @param index The index of the object to replace * @return The object to replace the object with */ | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /** * @brief A block for replacing values in an OFMutableArray. * * @param object The object to replace * @param index The index of the object to replace * @return The object to replace the object with */ typedef id _Nonnull (^OFArrayReplaceBlock)(id object, size_t index); #endif /** * @class OFMutableArray OFArray.h ObjFW/OFArray.h * * @brief An abstract class for storing, adding and removing objects in an * array. |
︙ | ︙ | |||
80 81 82 83 84 85 86 | /** * @brief Inserts an object to the OFArray at the specified index. * * @param object An object to add * @param index The index where the object should be inserted */ | | < | | < | < | < | | | | | | < | < < < < | < | < < < < | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | /** * @brief Inserts an object to the OFArray at the specified index. * * @param object An object to add * @param index The index where the object should be inserted */ - (void)insertObject: (ObjectType)object atIndex: (size_t)index; /** * @brief Inserts the objects from the specified OFArray at the specified index. * * @param array An array of objects * @param index The index where the objects should be inserted */ - (void)insertObjectsFromArray: (OFArray OF_GENERIC(ObjectType) *)array atIndex: (size_t)index; /** * @brief Replaces all objects equivalent to the specified object with the * other specified object. * * @param oldObject The object to replace * @param newObject The replacement object */ - (void)replaceObject: (ObjectType)oldObject withObject: (ObjectType)newObject; /** * @brief Replaces the object at the specified index with the specified object. * * @param index The index of the object to replace * @param object The replacement object */ - (void)replaceObjectAtIndex: (size_t)index withObject: (ObjectType)object; /** * @brief Replaces the object at the specified index with the specified object. * * This method is the same as @ref replaceObjectAtIndex:withObject:. * * This method is also used by the subscripting syntax. * * @param index The index of the object to replace * @param object The replacement object */ - (void)setObject: (ObjectType)object atIndexedSubscript: (size_t)index; /** * @brief Replaces the first object that has the same address as the specified * object with the other specified object. * * @param oldObject The object to replace * @param newObject The replacement object */ - (void)replaceObjectIdenticalTo: (ObjectType)oldObject withObject: (ObjectType)newObject; /** * @brief Removes all objects equivalent to the specified object. * * @param object The object to remove */ - (void)removeObject: (ObjectType)object; /** * @brief Removes all objects that have the same address as the specified * object. * * @param object The object to remove */ - (void)removeObjectIdenticalTo: (ObjectType)object; /** * @brief Removes the object at the specified index. * * @param index The index of the object to remove */ - (void)removeObjectAtIndex: (size_t)index; /** * @brief Removes the objects in the specified range. * * @param range The range of the objects to remove */ - (void)removeObjectsInRange: (OFRange)range; /** * @brief Removes the last object. */ - (void)removeLastObject; /** * @brief Removes all objects. */ - (void)removeAllObjects; #ifdef OF_HAVE_BLOCKS /** * @brief Replaces each object with the object returned by the block. * * @param block The block which returns a new object for each object */ - (void)replaceObjectsUsingBlock: (OFArrayReplaceBlock)block; #endif /** * @brief Exchange the objects at the specified indices. * * @param index1 The index of the first object to exchange * @param index2 The index of the second object to exchange */ - (void)exchangeObjectAtIndex: (size_t)index1 withObjectAtIndex: (size_t)index2; /** * @brief Sorts the array in ascending order. */ - (void)sort; /** * @brief Sorts the array using the specified selector and options. * * @param selector The selector to use to sort the array. It's signature * should be the same as that of -[compare:]. * @param options The options to use when sorting the array */ - (void)sortUsingSelector: (SEL)selector options: (OFArraySortOptions)options; #ifdef OF_HAVE_BLOCKS /** * @brief Sorts the array using the specified comparator and options. * * @param comparator The comparator to use to sort the array * @param options The options to use when sorting the array */ - (void)sortUsingComparator: (OFComparator)comparator options: (OFArraySortOptions)options; #endif /** * @brief Reverts the order of the objects in the array. */ - (void)reverse; |
︙ | ︙ |
Modified src/OFMutableArray.m from [ec4d8f9c48] to [8e711f8f4a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
32 33 34 35 36 37 38 | static struct { Class isa; } placeholder; @interface OFMutableArrayPlaceholder: OFMutableArray @end | | | | | | | | | | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | static struct { Class isa; } placeholder; @interface OFMutableArrayPlaceholder: OFMutableArray @end static OFComparisonResult compare(id left, id right, SEL selector) { OFComparisonResult (*comparator)(id, SEL, id) = (OFComparisonResult (*)(id, SEL, id)) [left methodForSelector: selector]; return comparator(left, selector, right); } static void quicksort(OFMutableArray *array, size_t left, size_t right, SEL selector, OFArraySortOptions options) { OFComparisonResult ascending, descending; if (options & OFArraySortDescending) { ascending = OFOrderedDescending; descending = OFOrderedAscending; } else { ascending = OFOrderedAscending; descending = OFOrderedDescending; } while (left < right) { size_t i = left; size_t j = right - 1; id pivot = [array objectAtIndex: right]; |
︙ | ︙ | |||
90 91 92 93 94 95 96 | left = i + 1; } } #ifdef OF_HAVE_BLOCKS static void quicksortWithBlock(OFMutableArray *array, size_t left, size_t right, | | | | | | | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | left = i + 1; } } #ifdef OF_HAVE_BLOCKS static void quicksortWithBlock(OFMutableArray *array, size_t left, size_t right, OFComparator comparator, OFArraySortOptions options) { OFComparisonResult ascending, descending; if (options & OFArraySortDescending) { ascending = OFOrderedDescending; descending = OFOrderedAscending; } else { ascending = OFOrderedAscending; descending = OFOrderedDescending; } while (left < right) { size_t i = left; size_t j = right - 1; id pivot = [array objectAtIndex: right]; |
︙ | ︙ | |||
163 164 165 166 167 168 169 | ret = [[OFMutableAdjacentArray alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } | | < | < | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | ret = [[OFMutableAdjacentArray alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { return (id)[[OFMutableAdjacentArray alloc] initWithObject: firstObject arguments: arguments]; } - (instancetype)initWithArray: (OFArray *)array { return (id)[[OFMutableAdjacentArray alloc] initWithArray: array]; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { return (id)[[OFMutableAdjacentArray alloc] initWithObjects: objects count: count]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { |
︙ | ︙ | |||
255 256 257 258 259 260 261 | - (id)copy { return [[OFArray alloc] initWithArray: self]; } - (void)addObject: (id)object { | | < | < | < | < | < | < < | | < | < | | | < < | | < < | < | < | 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | - (id)copy { return [[OFArray alloc] initWithArray: self]; } - (void)addObject: (id)object { [self insertObject: object atIndex: self.count]; } - (void)addObjectsFromArray: (OFArray *)array { [self insertObjectsFromArray: array atIndex: self.count]; } - (void)insertObject: (id)object atIndex: (size_t)idx { OF_UNRECOGNIZED_SELECTOR } - (void)insertObjectsFromArray: (OFArray *)array atIndex: (size_t)idx { size_t i = 0; for (id object in array) [self insertObject: object atIndex: idx + i++]; } - (void)replaceObjectAtIndex: (size_t)idx withObject: (id)object { OF_UNRECOGNIZED_SELECTOR } - (void)setObject: (id)object atIndexedSubscript: (size_t)idx { [self replaceObjectAtIndex: idx withObject: object]; } - (void)replaceObject: (id)oldObject withObject: (id)newObject { size_t count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; count = self.count; for (size_t i = 0; i < count; i++) if ([[self objectAtIndex: i] isEqual: oldObject]) [self replaceObjectAtIndex: i withObject: newObject]; } - (void)replaceObjectIdenticalTo: (id)oldObject withObject: (id)newObject { size_t count; if (oldObject == nil || newObject == nil) @throw [OFInvalidArgumentException exception]; count = self.count; for (size_t i = 0; i < count; i++) { if ([self objectAtIndex: i] == oldObject) { [self replaceObjectAtIndex: i withObject: newObject]; return; } } } - (void)removeObjectAtIndex: (size_t)idx |
︙ | ︙ | |||
351 352 353 354 355 356 357 | count = self.count; for (size_t i = 0; i < count; i++) { if ([[self objectAtIndex: i] isEqual: object]) { [self removeObjectAtIndex: i]; | > | > > | > | | | | < | < | < | < | < | | | | < | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | count = self.count; for (size_t i = 0; i < count; i++) { if ([[self objectAtIndex: i] isEqual: object]) { [self removeObjectAtIndex: i]; i--; count--; continue; } } } - (void)removeObjectIdenticalTo: (id)object { size_t count; if (object == nil) @throw [OFInvalidArgumentException exception]; count = self.count; for (size_t i = 0; i < count; i++) { if ([self objectAtIndex: i] == object) { [self removeObjectAtIndex: i]; i--; count--; continue; } } } - (void)removeObjectsInRange: (OFRange)range { for (size_t i = 0; i < range.length; i++) [self removeObjectAtIndex: range.location]; } - (void)removeLastObject { size_t count = self.count; if (count == 0) return; [self removeObjectAtIndex: count - 1]; } - (void)removeAllObjects { [self removeObjectsInRange: OFRangeMake(0, self.count)]; } #ifdef OF_HAVE_BLOCKS - (void)replaceObjectsUsingBlock: (OFArrayReplaceBlock)block { [self enumerateObjectsUsingBlock: ^ (id object, size_t idx, bool *stop) { id new = block(object, idx); if (new != object) [self replaceObjectAtIndex: idx withObject: new]; }]; } #endif - (void)exchangeObjectAtIndex: (size_t)idx1 withObjectAtIndex: (size_t)idx2 { id object1 = [self objectAtIndex: idx1]; id object2 = [self objectAtIndex: idx2]; [object1 retain]; @try { [self replaceObjectAtIndex: idx1 withObject: object2]; [self replaceObjectAtIndex: idx2 withObject: object1]; } @finally { [object1 release]; } } - (void)sort { [self sortUsingSelector: @selector(compare:) options: 0]; } - (void)sortUsingSelector: (SEL)selector options: (OFArraySortOptions)options { size_t count = self.count; if (count == 0 || count == 1) return; quicksort(self, 0, count - 1, selector, options); } #ifdef OF_HAVE_BLOCKS - (void)sortUsingComparator: (OFComparator)comparator options: (OFArraySortOptions)options { size_t count = self.count; if (count == 0 || count == 1) return; quicksortWithBlock(self, 0, count - 1, comparator, options); } #endif - (void)reverse { size_t i, j, count = self.count; if (count == 0 || count == 1) return; for (i = 0, j = count - 1; i < j; i++, j--) [self exchangeObjectAtIndex: i withObjectAtIndex: j]; } - (void)makeImmutable { } @end |
Modified src/OFMutableData.h from [1a536a9853] to [5eba71457e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | * @brief All items of the OFMutableData as a C array. * * @warning The pointer is only valid until the OFMutableData is changed! * * Modifying the returned array directly is allowed and will change the contents * of the data. */ | | > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | * @brief All items of the OFMutableData as a C array. * * @warning The pointer is only valid until the OFMutableData is changed! * * Modifying the returned array directly is allowed and will change the contents * of the data. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) void *mutableItems OF_RETURNS_INNER_POINTER; /** * @brief The first item of the OFMutableData or `NULL`. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) void *mutableFirstItem OF_RETURNS_INNER_POINTER; |
︙ | ︙ | |||
84 85 86 87 88 89 90 | * @brief Creates a new OFMutableData with enough memory to hold the specified * number of items which all have the same specified size. * * @param itemSize The size of a single element in the OFMutableData * @param capacity The initial capacity for the OFMutableData * @return A new autoreleased OFMutableData */ | | < | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | * @brief Creates a new OFMutableData with enough memory to hold the specified * number of items which all have the same specified size. * * @param itemSize The size of a single element in the OFMutableData * @param capacity The initial capacity for the OFMutableData * @return A new autoreleased OFMutableData */ + (instancetype)dataWithItemSize: (size_t)itemSize capacity: (size_t)capacity; /** * @brief Initializes an already allocated OFMutableData with an item size of 1. * * @return An initialized OFMutableData */ - (instancetype)init; |
︙ | ︙ | |||
122 123 124 125 126 127 128 | * hold the the specified number of items which all have the same * specified size. * * @param itemSize The size of a single element in the OFMutableData * @param capacity The initial capacity for the OFMutableData * @return An initialized OFMutableData */ | | < | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | * hold the the specified number of items which all have the same * specified size. * * @param itemSize The size of a single element in the OFMutableData * @param capacity The initial capacity for the OFMutableData * @return An initialized OFMutableData */ - (instancetype)initWithItemSize: (size_t)itemSize capacity: (size_t)capacity; /** * @brief Returns a specific item of the OFMutableData. * * Modifying the returned item directly is allowed and will change the contents * of the data. * |
︙ | ︙ | |||
149 150 151 152 153 154 155 | /** * @brief Adds an item to the OFMutableData at the specified index. * * @param item A pointer to an arbitrary item * @param index The index where the item should be added */ | | < | < | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | /** * @brief Adds an item to the OFMutableData at the specified index. * * @param item A pointer to an arbitrary item * @param index The index where the item should be added */ - (void)insertItem: (const void *)item atIndex: (size_t)index; /** * @brief Adds items from a C array to the OFMutableData. * * @param items A C array containing the items to add * @param count The number of items to add */ - (void)addItems: (const void *)items count: (size_t)count; /** * @brief Adds items from a C array to the OFMutableData at the specified index. * * @param items A C array containing the items to add * @param index The index where the items should be added * @param count The number of items to add |
︙ | ︙ | |||
192 193 194 195 196 197 198 | - (void)removeItemAtIndex: (size_t)index; /** * @brief Removes the specified amount of items at the specified index. * * @param range The range of items to remove */ | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | - (void)removeItemAtIndex: (size_t)index; /** * @brief Removes the specified amount of items at the specified index. * * @param range The range of items to remove */ - (void)removeItemsInRange: (OFRange)range; /** * @brief Removes the last item. */ - (void)removeLastItem; /** |
︙ | ︙ |
Modified src/OFMutableData.m from [6ca92c6b7f] to [2aa51e2819].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
40 41 42 43 44 45 46 | } + (instancetype)dataWithCapacity: (size_t)capacity { return [[[self alloc] initWithCapacity: capacity] autorelease]; } | | < > > | < < < | > < > | < < < > | < < | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | } + (instancetype)dataWithCapacity: (size_t)capacity { return [[[self alloc] initWithCapacity: capacity] autorelease]; } + (instancetype)dataWithItemSize: (size_t)itemSize capacity: (size_t)capacity { return [[[self alloc] initWithItemSize: itemSize capacity: capacity] autorelease]; } - (instancetype)init { self = [super init]; _itemSize = 1; _freeWhenDone = true; return self; } - (instancetype)initWithItemSize: (size_t)itemSize { self = [super init]; @try { if (itemSize == 0) @throw [OFInvalidArgumentException exception]; _itemSize = itemSize; _freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithCapacity: (size_t)capacity { return [self initWithItemSize: 1 capacity: capacity]; } - (instancetype)initWithItemSize: (size_t)itemSize capacity: (size_t)capacity { self = [super init]; @try { if (itemSize == 0) @throw [OFInvalidArgumentException exception]; _items = OFAllocMemory(capacity, itemSize); _itemSize = itemSize; _capacity = capacity; _freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithItems: (const void *)items count: (size_t)count itemSize: (size_t)itemSize { self = [super initWithItems: items count: count itemSize: itemSize]; _capacity = _count; return self; } - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone { self = [self initWithItems: items count: count itemSize: itemSize]; if (freeWhenDone) OFFreeMemory(items); return self; } - (instancetype)initWithStringRepresentation: (OFString *)string { self = [super initWithStringRepresentation: string]; |
︙ | ︙ | |||
167 168 169 170 171 172 173 | { if (_items == NULL || _count == 0) return NULL; return _items + (_count - 1) * _itemSize; } | | > | < < < | | < | < < | < < < | < < | < < | | | | < < | < < | < > | < > > > > > > > > > | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 | { if (_items == NULL || _count == 0) return NULL; return _items + (_count - 1) * _itemSize; } - (OFData *)subdataWithRange: (OFRange)range { if (range.length > SIZE_MAX - range.location || range.location + range.length > _count) @throw [OFOutOfRangeException exception]; return [OFData dataWithItems: _items + (range.location * _itemSize) count: range.length itemSize: _itemSize]; } - (void)addItem: (const void *)item { if (SIZE_MAX - _count < 1) @throw [OFOutOfRangeException exception]; if (_count + 1 > _capacity) { _items = OFResizeMemory(_items, _count + 1, _itemSize); _capacity = _count + 1; } memcpy(_items + _count * _itemSize, item, _itemSize); _count++; } - (void)insertItem: (const void *)item atIndex: (size_t)idx { [self insertItems: item atIndex: idx count: 1]; } - (void)addItems: (const void *)items count: (size_t)count { if (count > SIZE_MAX - _count) @throw [OFOutOfRangeException exception]; if (_count + count > _capacity) { _items = OFResizeMemory(_items, _count + count, _itemSize); _capacity = _count + count; } memcpy(_items + _count * _itemSize, items, count * _itemSize); _count += count; } - (void)insertItems: (const void *)items atIndex: (size_t)idx count: (size_t)count { if (count > SIZE_MAX - _count || idx > _count) @throw [OFOutOfRangeException exception]; if (_count + count > _capacity) { _items = OFResizeMemory(_items, _count + count, _itemSize); _capacity = _count + count; } memmove(_items + (idx + count) * _itemSize, _items + idx * _itemSize, (_count - idx) * _itemSize); memcpy(_items + idx * _itemSize, items, count * _itemSize); _count += count; } - (void)increaseCountBy: (size_t)count { if (count > SIZE_MAX - _count) @throw [OFOutOfRangeException exception]; if (_count + count > _capacity) { _items = OFResizeMemory(_items, _count + count, _itemSize); _capacity = _count + count; } memset(_items + _count * _itemSize, '\0', count * _itemSize); _count += count; } - (void)removeItemAtIndex: (size_t)idx { [self removeItemsInRange: OFRangeMake(idx, 1)]; } - (void)removeItemsInRange: (OFRange)range { if (range.length > SIZE_MAX - range.location || range.location + range.length > _count) @throw [OFOutOfRangeException exception]; memmove(_items + range.location * _itemSize, _items + (range.location + range.length) * _itemSize, (_count - range.location - range.length) * _itemSize); _count -= range.length; @try { _items = OFResizeMemory(_items, _count, _itemSize); _capacity = _count; } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } - (void)removeLastItem { if (_count == 0) return; _count--; @try { _items = OFResizeMemory(_items, _count, _itemSize); _capacity = _count; } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only made it smaller */ } } - (void)removeAllItems { OFFreeMemory(_items); _items = NULL; _count = 0; _capacity = 0; } - (id)copy { return [[OFData alloc] initWithItems: _items count: _count itemSize: _itemSize]; } - (void)makeImmutable { if (_capacity != _count) { @try { _items = OFResizeMemory(_items, _count, _itemSize); _capacity = _count; } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only made it smaller */ } } object_setClass(self, [OFData class]); } @end |
Modified src/OFMutableDictionary.h from [456cb78a11] to [851a8f19f7].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | /** * @brief A block for replacing objects in an OFMutableDictionary. * * @param key The key of the object to replace * @param object The object to replace * @return The object to replace the object with */ | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /** * @brief A block for replacing objects in an OFMutableDictionary. * * @param key The key of the object to replace * @param object The object to replace * @return The object to replace the object with */ typedef id _Nonnull (^OFDictionaryReplaceBlock)(id key, id object); #endif /** * @class OFMutableDictionary OFDictionary.h ObjFW/OFDictionary.h * * @brief An abstract class for storing and changing objects in a dictionary. * |
︙ | ︙ | |||
69 70 71 72 73 74 75 | * @brief Sets an object for a key. * * A key can be any object that conforms to the OFCopying protocol. * * @param key The key to set * @param object The object to set the key to */ | | < | < | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | * @brief Sets an object for a key. * * A key can be any object that conforms to the OFCopying protocol. * * @param key The key to set * @param object The object to set the key to */ - (void)setObject: (ObjectType)object forKey: (KeyType)key; /** * @brief Sets an object for a key. * * A key can be any object that conforms to the OFCopying protocol. * * This method is also used by the subscripting syntax. * * @param key The key to set * @param object The object to set the key to. If it is nil, this is equal to * calling @ref removeObjectForKey:. */ - (void)setObject: (nullable ObjectType)object forKeyedSubscript: (KeyType)key; /** * @brief Removes the object for the specified key from the dictionary. * * @param key The key whose object should be removed */ - (void)removeObjectForKey: (KeyType)key; |
︙ | ︙ | |||
112 113 114 115 116 117 118 | #ifdef OF_HAVE_BLOCKS /** * @brief Replaces each object with the object returned by the block. * * @param block The block which returns a new object for each object */ | | | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | #ifdef OF_HAVE_BLOCKS /** * @brief Replaces each object with the object returned by the block. * * @param block The block which returns a new object for each object */ - (void)replaceObjectsUsingBlock: (OFDictionaryReplaceBlock)block; #endif /** * @brief Converts the mutable dictionary to an immutable dictionary. */ - (void)makeImmutable; #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef KeyType # undef ObjectType #endif @end OF_ASSUME_NONNULL_END |
Modified src/OFMutableDictionary.m from [178e351b06] to [459ca84c71].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
38 39 40 41 42 43 44 | - (instancetype)initWithDictionary: (OFDictionary *)dictionary { return (id)[[OFMutableMapTableDictionary alloc] initWithDictionary: dictionary]; } | | < | < | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | - (instancetype)initWithDictionary: (OFDictionary *)dictionary { return (id)[[OFMutableMapTableDictionary alloc] initWithDictionary: dictionary]; } - (instancetype)initWithObject: (id)object forKey: (id)key { return (id)[[OFMutableMapTableDictionary alloc] initWithObject: object forKey: key]; } - (instancetype)initWithObjects: (OFArray *)objects forKeys: (OFArray *)keys { return (id)[[OFMutableMapTableDictionary alloc] initWithObjects: objects forKeys: keys]; } - (instancetype)initWithObjects: (id const *)objects forKeys: (id const *)keys |
︙ | ︙ | |||
74 75 76 77 78 79 80 | ret = (id)[[OFMutableMapTableDictionary alloc] initWithKey: firstKey arguments: arguments]; va_end(arguments); return ret; } | | < | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | ret = (id)[[OFMutableMapTableDictionary alloc] initWithKey: firstKey arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithKey: (id)firstKey arguments: (va_list)arguments { return (id)[[OFMutableMapTableDictionary alloc] initWithKey: firstKey arguments: arguments]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { |
︙ | ︙ | |||
154 155 156 157 158 159 160 | } - (instancetype)initWithCapacity: (size_t)capacity { OF_INVALID_INIT_METHOD } | | < | < | < | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | } - (instancetype)initWithCapacity: (size_t)capacity { OF_INVALID_INIT_METHOD } - (void)setObject: (id)object forKey: (id)key { OF_UNRECOGNIZED_SELECTOR } - (void)setObject: (id)object forKeyedSubscript: (id)key { if (object != nil) [self setObject: object forKey: key]; else [self removeObjectForKey: key]; } - (void)removeObjectForKey: (id)key { OF_UNRECOGNIZED_SELECTOR |
︙ | ︙ | |||
199 200 201 202 203 204 205 | void *pool = objc_autoreleasePoolPush(); OFEnumerator *keyEnumerator = [dictionary keyEnumerator]; OFEnumerator *objectEnumerator = [dictionary objectEnumerator]; id key, object; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) | | < | | < | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | void *pool = objc_autoreleasePoolPush(); OFEnumerator *keyEnumerator = [dictionary keyEnumerator]; OFEnumerator *objectEnumerator = [dictionary objectEnumerator]; id key, object; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) [self setObject: object forKey: key]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (void)replaceObjectsUsingBlock: (OFDictionaryReplaceBlock)block { [self enumerateKeysAndObjectsUsingBlock: ^ (id key, id object, bool *stop) { id new = block(key, object); if (new != object) { [self setObject: block(key, object) forKey: key]; } }]; } #endif - (void)makeImmutable { } @end |
Modified src/OFMutableLHAArchiveEntry.h from [ec3dafe13e] to [4253f691f5].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMutableLHAArchiveEntry.m from [164ba61cd2] to [8d9a6a0cb1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMutableMapTableDictionary.h from [64ba6e9547] to [e3ea116447].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMutableMapTableDictionary.m from [9a2bd23662] to [eda929d7fd].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | @implementation OFMutableMapTableDictionary + (void)initialize { if (self == [OFMutableMapTableDictionary class]) [self inheritMethodsFromClass: [OFMapTableDictionary class]]; } | | < | < | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | @implementation OFMutableMapTableDictionary + (void)initialize { if (self == [OFMutableMapTableDictionary class]) [self inheritMethodsFromClass: [OFMapTableDictionary class]]; } - (void)setObject: (id)object forKey: (id)key { [_mapTable setObject: object forKey: key]; } - (void)removeObjectForKey: (id)key { [_mapTable removeObjectForKey: key]; } - (void)removeAllObjects { [_mapTable removeAllObjects]; } #ifdef OF_HAVE_BLOCKS - (void)replaceObjectsUsingBlock: (OFDictionaryReplaceBlock)block { @try { [_mapTable replaceObjectsUsingBlock: ^ void *(void *key, void *object) { return block(key, object); }]; } @catch (OFEnumerationMutationException *e) { |
︙ | ︙ |
Modified src/OFMutableMapTableSet.h from [b78ac106e9] to [ee94211a1c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMutableMapTableSet.m from [d444b25d5d] to [134371a3b6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
26 27 28 29 30 31 32 | { if (self == [OFMutableMapTableSet class]) [self inheritMethodsFromClass: [OFMapTableSet class]]; } - (void)addObject: (id)object { | | < | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | { if (self == [OFMutableMapTableSet class]) [self inheritMethodsFromClass: [OFMapTableSet class]]; } - (void)addObject: (id)object { [_mapTable setObject: (void *)1 forKey: object]; } - (void)removeObject: (id)object { [_mapTable removeObjectForKey: object]; } |
︙ | ︙ |
Modified src/OFMutablePair.h from [d92de22cb9] to [fd02ba0f90].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMutablePair.m from [d45cf41ccb] to [6901454ea9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
35 36 37 38 39 40 41 | _secondObject = [secondObject retain]; [old release]; } - (id)copy { OFMutablePair *copy = [self mutableCopy]; | < < | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | _secondObject = [secondObject retain]; [old release]; } - (id)copy { OFMutablePair *copy = [self mutableCopy]; [copy makeImmutable]; return copy; } - (void)makeImmutable { object_setClass(self, [OFPair class]); } @end |
Modified src/OFMutableSet.h from [596b811b75] to [c05177c6a6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMutableSet.m from [460faa4705] to [b126234b89].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
56 57 58 59 60 61 62 | ret = [[OFMutableMapTableSet alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } | | < | < | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | ret = [[OFMutableMapTableSet alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { return (id)[[OFMutableMapTableSet alloc] initWithObjects: objects count: count]; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { return (id)[[OFMutableMapTableSet alloc] initWithObject: firstObject arguments: arguments]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { |
︙ | ︙ | |||
168 169 170 171 172 173 174 | - (void)intersectSet: (OFSet *)set { void *pool = objc_autoreleasePoolPush(); size_t count = self.count; id *cArray; | < < | | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | - (void)intersectSet: (OFSet *)set { void *pool = objc_autoreleasePoolPush(); size_t count = self.count; id *cArray; cArray = OFAllocMemory(count, sizeof(id)); @try { size_t i; i = 0; for (id object in self) { assert(i < count); cArray[i++] = object; } for (i = 0; i < count; i++) if (![set containsObject: cArray[i]]) [self removeObject: cArray[i]]; } @finally { OFFreeMemory(cArray); } objc_autoreleasePoolPop(pool); } - (void)unionSet: (OFSet *)set { |
︙ | ︙ |
Modified src/OFMutableString.h from [4d268ac292] to [9300a1f2cf].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
31 32 33 34 35 36 37 | @interface OFMutableString: OFString /** * @brief Sets the character at the specified index. * * @param character The character to set * @param index The index where to set the character */ | | < | < | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | @interface OFMutableString: OFString /** * @brief Sets the character at the specified index. * * @param character The character to set * @param index The index where to set the character */ - (void)setCharacter: (OFUnichar)character atIndex: (size_t)index; /** * @brief Appends another OFString to the OFMutableString. * * @param string An OFString to append */ - (void)appendString: (OFString *)string; /** * @brief Appends the specified characters to the OFMutableString. * * @param characters An array of characters to append * @param length The length of the array of characters */ - (void)appendCharacters: (const OFUnichar *)characters length: (size_t)length; /** * @brief Appends a UTF-8 encoded C string to the OFMutableString. * * @param UTF8String A UTF-8 encoded C string to append */ - (void)appendUTF8String: (const char *)UTF8String; |
︙ | ︙ | |||
74 75 76 77 78 79 80 | /** * @brief Appends a C string with the specified encoding to the OFMutableString. * * @param cString A C string to append * @param encoding The encoding of the C string */ - (void)appendCString: (const char *)cString | | | | | | | | < | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | /** * @brief Appends a C string with the specified encoding to the OFMutableString. * * @param cString A C string to append * @param encoding The encoding of the C string */ - (void)appendCString: (const char *)cString encoding: (OFStringEncoding)encoding; /** * @brief Appends a C string with the specified encoding and length to the * OFMutableString. * * @param cString A C string to append * @param encoding The encoding of the C string * @param cStringLength The length of the UTF-8 encoded C string */ - (void)appendCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength; /** * @brief Appends a formatted string to the OFMutableString. * * See `printf` for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `OFUnichar` and `%S` for * `const OFUnichar *`. * * @param format A format string which generates the string to append */ - (void)appendFormat: (OFConstantString *)format, ...; /** * @brief Appends a formatted string to the OFMutableString. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `OFUnichar` and `%S` for * `const OFUnichar *`. * * @param format A format string which generates the string to append * @param arguments The arguments used in the format string */ - (void)appendFormat: (OFConstantString *)format arguments: (va_list)arguments; /** * @brief Prepends another OFString to the OFMutableString. * * @param string An OFString to prepend */ - (void)prependString: (OFString *)string; |
︙ | ︙ | |||
149 150 151 152 153 154 155 | /** * @brief Inserts a string at the specified index. * * @param string The string to insert * @param index The index */ | | < | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | /** * @brief Inserts a string at the specified index. * * @param string The string to insert * @param index The index */ - (void)insertString: (OFString *)string atIndex: (size_t)index; /** * @brief Deletes the characters at the specified range. * * @param range The range of the characters which should be removed */ - (void)deleteCharactersInRange: (OFRange)range; /** * @brief Replaces the characters at the specified range. * * @param range The range of the characters which should be replaced * @param replacement The string to the replace the characters with */ - (void)replaceCharactersInRange: (OFRange)range withString: (OFString *)replacement; /** * @brief Replaces all occurrences of a string with another string. * * @param string The string to replace * @param replacement The string with which it should be replaced |
︙ | ︙ | |||
190 191 192 193 194 195 196 | * @param options Options modifying search behaviour * Possible values: None yet * @param range The range in which the string should be replaced */ - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options | | | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | * @param options Options modifying search behaviour * Possible values: None yet * @param range The range in which the string should be replaced */ - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (OFRange)range; /** * @brief Deletes all whitespaces at the beginning of the string. */ - (void)deleteLeadingWhitespaces; /** |
︙ | ︙ |
Modified src/OFMutableString.m from [bb86d6b9da] to [a015aada74].
1 | /* | < < | > < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdarg.h> #include <stdlib.h> #include <string.h> #import "OFString.h" #import "OFASPrintF.h" #import "OFMutableUTF8String.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "unicode.h" static struct { Class isa; } placeholder; @interface OFMutableStringPlaceholder: OFMutableString |
︙ | ︙ | |||
54 55 56 57 58 59 60 | { return (id)[[OFMutableUTF8String alloc] initWithUTF8String: UTF8String length: UTF8StringLength]; } - (instancetype)initWithCString: (const char *)cString | | | | | | | | | | | | | | | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | { return (id)[[OFMutableUTF8String alloc] initWithUTF8String: UTF8String length: UTF8StringLength]; } - (instancetype)initWithCString: (const char *)cString encoding: (OFStringEncoding)encoding { return (id)[[OFMutableUTF8String alloc] initWithCString: cString encoding: encoding]; } - (instancetype)initWithCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength { return (id)[[OFMutableUTF8String alloc] initWithCString: cString encoding: encoding length: cStringLength]; } - (instancetype)initWithString: (OFString *)string { return (id)[[OFMutableUTF8String alloc] initWithString: string]; } - (instancetype)initWithCharacters: (const OFUnichar *)characters length: (size_t)length { return (id)[[OFMutableUTF8String alloc] initWithCharacters: characters length: length]; } - (instancetype)initWithUTF16String: (const OFChar16 *)string { return (id)[[OFMutableUTF8String alloc] initWithUTF16String: string]; } - (instancetype)initWithUTF16String: (const OFChar16 *)string length: (size_t)length { return (id)[[OFMutableUTF8String alloc] initWithUTF16String: string length: length]; } - (instancetype)initWithUTF16String: (const OFChar16 *)string byteOrder: (OFByteOrder)byteOrder { return (id)[[OFMutableUTF8String alloc] initWithUTF16String: string byteOrder: byteOrder]; } - (instancetype)initWithUTF16String: (const OFChar16 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder { return (id)[[OFMutableUTF8String alloc] initWithUTF16String: string length: length byteOrder: byteOrder]; } - (instancetype)initWithUTF32String: (const OFChar32 *)string { return (id)[[OFMutableUTF8String alloc] initWithUTF32String: string]; } - (instancetype)initWithUTF32String: (const OFChar32 *)string length: (size_t)length { return (id)[[OFMutableUTF8String alloc] initWithUTF32String: string length: length]; } - (instancetype)initWithUTF32String: (const OFChar32 *)string byteOrder: (OFByteOrder)byteOrder { return (id)[[OFMutableUTF8String alloc] initWithUTF32String: string byteOrder: byteOrder]; } - (instancetype)initWithUTF32String: (const OFChar32 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder { return (id)[[OFMutableUTF8String alloc] initWithUTF32String: string length: length byteOrder: byteOrder]; } - (instancetype)initWithFormat: (OFConstantString *)format, ... |
︙ | ︙ | |||
164 165 166 167 168 169 170 | #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path { return (id)[[OFMutableUTF8String alloc] initWithContentsOfFile: path]; } - (instancetype)initWithContentsOfFile: (OFString *)path | | < | < | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path { return (id)[[OFMutableUTF8String alloc] initWithContentsOfFile: path]; } - (instancetype)initWithContentsOfFile: (OFString *)path encoding: (OFStringEncoding)encoding { return (id)[[OFMutableUTF8String alloc] initWithContentsOfFile: path encoding: encoding]; } #endif - (instancetype)initWithContentsOfURL: (OFURL *)URL { return (id)[[OFMutableUTF8String alloc] initWithContentsOfURL: URL]; } - (instancetype)initWithContentsOfURL: (OFURL *)URL encoding: (OFStringEncoding)encoding { return (id)[[OFMutableUTF8String alloc] initWithContentsOfURL: URL encoding: encoding]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFMutableUTF8String alloc] initWithSerialization: element]; } - (instancetype)retain |
︙ | ︙ | |||
228 229 230 231 232 233 234 | if (self == [OFMutableString class]) return (id)&placeholder; return [super alloc]; } #ifdef OF_HAVE_UNICODE_TABLES | | | | | | | | < | > | | < | | | < | | < | < | < < | < < | < | < < < < < < | < < | < < | < | | < | < | | < | < | | | | | | | | | | | | < < < < | > > > | < | < | < | < | | < | | | | | | | | | | | | | | | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | if (self == [OFMutableString class]) return (id)&placeholder; return [super alloc]; } #ifdef OF_HAVE_UNICODE_TABLES - (void)of_convertWithWordStartTable: (const OFUnichar *const [])startTable wordMiddleTable: (const OFUnichar *const [])middleTable wordStartTableSize: (size_t)startTableSize wordMiddleTableSize: (size_t)middleTableSize { void *pool = objc_autoreleasePoolPush(); const OFUnichar *characters = self.characters; size_t length = self.length; bool isStart = true; for (size_t i = 0; i < length; i++) { const OFUnichar *const *table; size_t tableSize; OFUnichar c = characters[i]; if (isStart) { table = startTable; tableSize = middleTableSize; } else { table = middleTable; tableSize = middleTableSize; } if (c >> 8 < tableSize && table[c >> 8][c & 0xFF]) [self setCharacter: table[c >> 8][c & 0xFF] atIndex: i]; isStart = OFASCIIIsSpace(c); } objc_autoreleasePoolPop(pool); } #else static void convert(OFMutableString *self, char (*startFunction)(char), char (*middleFunction)(char)) { void *pool = objc_autoreleasePoolPush(); const OFUnichar *characters = self.characters; size_t length = self.length; bool isStart = true; for (size_t i = 0; i < length; i++) { char (*function)(char) = (isStart ? startFunction : middleFunction); OFUnichar c = characters[i]; if (c <= 0x7F) [self setCharacter: (int)function(c) atIndex: i]; isStart = OFASCIIIsSpace(c); } objc_autoreleasePoolPop(pool); } #endif - (void)setCharacter: (OFUnichar)character atIndex: (size_t)idx { void *pool = objc_autoreleasePoolPush(); OFString *string = [OFString stringWithCharacters: &character length: 1]; [self replaceCharactersInRange: OFRangeMake(idx, 1) withString: string]; objc_autoreleasePoolPop(pool); } - (void)appendString: (OFString *)string { [self insertString: string atIndex: self.length]; } - (void)appendCharacters: (const OFUnichar *)characters length: (size_t)length { void *pool = objc_autoreleasePoolPush(); [self appendString: [OFString stringWithCharacters: characters length: length]]; objc_autoreleasePoolPop(pool); } - (void)appendUTF8String: (const char *)UTF8String { void *pool = objc_autoreleasePoolPush(); [self appendString: [OFString stringWithUTF8String: UTF8String]]; objc_autoreleasePoolPop(pool); } - (void)appendUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength { void *pool = objc_autoreleasePoolPush(); [self appendString: [OFString stringWithUTF8String: UTF8String length: UTF8StringLength]]; objc_autoreleasePoolPop(pool); } - (void)appendCString: (const char *)cString encoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); [self appendString: [OFString stringWithCString: cString encoding: encoding]]; objc_autoreleasePoolPop(pool); } - (void)appendCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength { void *pool = objc_autoreleasePoolPush(); [self appendString: [OFString stringWithCString: cString encoding: encoding length: cStringLength]]; objc_autoreleasePoolPop(pool); } - (void)appendFormat: (OFConstantString *)format, ... { va_list arguments; va_start(arguments, format); [self appendFormat: format arguments: arguments]; va_end(arguments); } - (void)appendFormat: (OFConstantString *)format arguments: (va_list)arguments { char *UTF8String; int UTF8StringLength; if (format == nil) @throw [OFInvalidArgumentException exception]; if ((UTF8StringLength = OFVASPrintF(&UTF8String, format.UTF8String, arguments)) == -1) @throw [OFInvalidFormatException exception]; @try { [self appendUTF8String: UTF8String length: UTF8StringLength]; } @finally { free(UTF8String); } } - (void)prependString: (OFString *)string { [self insertString: string atIndex: 0]; } - (void)reverse { size_t i, j, length = self.length; for (i = 0, j = length - 1; i < length / 2; i++, j--) { OFUnichar tmp = [self characterAtIndex: j]; [self setCharacter: [self characterAtIndex: i] atIndex: j]; [self setCharacter: tmp atIndex: i]; } } #ifdef OF_HAVE_UNICODE_TABLES - (void)uppercase { [self of_convertWithWordStartTable: OFUnicodeUppercaseTable wordMiddleTable: OFUnicodeUppercaseTable wordStartTableSize: OFUnicodeUppercaseTableSize wordMiddleTableSize: OFUnicodeUppercaseTableSize]; } - (void)lowercase { [self of_convertWithWordStartTable: OFUnicodeLowercaseTable wordMiddleTable: OFUnicodeLowercaseTable wordStartTableSize: OFUnicodeLowercaseTableSize wordMiddleTableSize: OFUnicodeLowercaseTableSize]; } - (void)capitalize { [self of_convertWithWordStartTable: OFUnicodeTitlecaseTable wordMiddleTable: OFUnicodeLowercaseTable wordStartTableSize: OFUnicodeTitlecaseTableSize wordMiddleTableSize: OFUnicodeLowercaseTableSize]; } #else - (void)uppercase { convert(self, OFASCIIToUpper, OFASCIIToUpper); } - (void)lowercase { convert(self, OFASCIIToLower, OFASCIIToLower); } - (void)capitalize { convert(self, OFASCIIToUpper, OFASCIIToLower); } #endif - (void)insertString: (OFString *)string atIndex: (size_t)idx { [self replaceCharactersInRange: OFRangeMake(idx, 0) withString: string]; } - (void)deleteCharactersInRange: (OFRange)range { [self replaceCharactersInRange: range withString: @""]; } - (void)replaceCharactersInRange: (OFRange)range withString: (OFString *)replacement { OF_UNRECOGNIZED_SELECTOR } - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement { [self replaceOccurrencesOfString: string withString: replacement options: 0 range: OFRangeMake(0, self.length)]; } - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (OFRange)range { void *pool = objc_autoreleasePoolPush(), *pool2; const OFUnichar *characters; const OFUnichar *searchCharacters = string.characters; size_t searchLength = string.length; size_t replacementLength = replacement.length; if (string == nil || replacement == nil) @throw [OFInvalidArgumentException exception]; if (range.length > SIZE_MAX - range.location || range.location + range.length > self.length) @throw [OFOutOfRangeException exception]; if (searchLength > range.length) { objc_autoreleasePoolPop(pool); return; } pool2 = objc_autoreleasePoolPush(); characters = self.characters; for (size_t i = range.location; i <= range.length - searchLength; i++) { if (memcmp(characters + i, searchCharacters, searchLength * sizeof(OFUnichar)) != 0) continue; [self replaceCharactersInRange: OFRangeMake(i, searchLength) withString: replacement]; range.length -= searchLength; range.length += replacementLength; i += replacementLength - 1; objc_autoreleasePoolPop(pool2); pool2 = objc_autoreleasePoolPush(); characters = self.characters; } objc_autoreleasePoolPop(pool); } - (void)deleteLeadingWhitespaces { void *pool = objc_autoreleasePoolPush(); const OFUnichar *characters = self.characters; size_t i, length = self.length; for (i = 0; i < length; i++) { OFUnichar c = characters[i]; if (!OFASCIIIsSpace(c)) break; } objc_autoreleasePoolPop(pool); [self deleteCharactersInRange: OFRangeMake(0, i)]; } - (void)deleteTrailingWhitespaces { void *pool; const OFUnichar *characters, *p; size_t length, d; length = self.length; if (length == 0) return; pool = objc_autoreleasePoolPush(); characters = self.characters; d = 0; for (p = characters + length - 1; p >= characters; p--) { if (!OFASCIIIsSpace(*p)) break; d++; } objc_autoreleasePoolPop(pool); [self deleteCharactersInRange: OFRangeMake(length - d, d)]; } - (void)deleteEnclosingWhitespaces { [self deleteLeadingWhitespaces]; [self deleteTrailingWhitespaces]; } |
︙ | ︙ |
Modified src/OFMutableTarArchiveEntry.h from [d27d9283d7] to [f3b4444a50].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
59 60 61 62 63 64 65 | * @brief The date of the last modification of the file. */ @property (readwrite, retain, nonatomic) OFDate *modificationDate; /** * @brief The type of the archive entry. * | | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | * @brief The date of the last modification of the file. */ @property (readwrite, retain, nonatomic) OFDate *modificationDate; /** * @brief The type of the archive entry. * * See @ref OFTarArchiveEntryType. */ @property (readwrite, nonatomic) OFTarArchiveEntryType type; /** * @brief The file name of the target (for a hard link or symbolic link). */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *targetFileName; |
︙ | ︙ |
Modified src/OFMutableTarArchiveEntry.m from [1fdec748d1] to [bfb188d370].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
64 65 66 67 68 69 70 | - (void)setModificationDate: (OFDate *)modificationDate { OFDate *old = _modificationDate; _modificationDate = [modificationDate retain]; [old release]; } | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | - (void)setModificationDate: (OFDate *)modificationDate { OFDate *old = _modificationDate; _modificationDate = [modificationDate retain]; [old release]; } - (void)setType: (OFTarArchiveEntryType)type { _type = type; } - (void)setTargetFileName: (OFString *)targetFileName { OFString *old = _targetFileName; |
︙ | ︙ |
Modified src/OFMutableTriple.h from [9542203867] to [9e67514e20].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMutableTriple.m from [af3517301d] to [a54e7551cb].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFMutableURL.h from [781d0b7833] to [28e4adf533].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
129 130 131 132 133 134 135 | /** * @brief The query part of the URL as a dictionary. * * For example, a query like `key1=value1&key2=value2` would correspond to the * following dictionary: * * @{ | | | | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | /** * @brief The query part of the URL as a dictionary. * * For example, a query like `key1=value1&key2=value2` would correspond to the * following dictionary: * * @{ * @"key1": @"value1", * @"key2": @"value2" * } */ @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFDictionary OF_GENERIC(OFString *, OFString *) *queryDictionary; /** * @brief The fragment part of the URL. |
︙ | ︙ | |||
175 176 177 178 179 180 181 | * @param isDirectory Whether the path is a directory, in which case a slash is * appened if there is no slash yet */ - (void)appendPathComponent: (OFString *)component isDirectory: (bool)isDirectory; /** | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | * @param isDirectory Whether the path is a directory, in which case a slash is * appened if there is no slash yet */ - (void)appendPathComponent: (OFString *)component isDirectory: (bool)isDirectory; /** * @brief Resolves relative subpaths. */ - (void)standardizePath; /** * @brief Converts the mutable URL to an immutable URL. */ - (void)makeImmutable; @end OF_ASSUME_NONNULL_END |
Modified src/OFMutableURL.m from [596cab8221] to [ce9685e8ce].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | # import "OFFileManager.h" #endif #import "OFNumber.h" #import "OFString.h" #import "OFInvalidFormatException.h" | < < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # import "OFFileManager.h" #endif #import "OFNumber.h" #import "OFString.h" #import "OFInvalidFormatException.h" @implementation OFMutableURL @dynamic scheme, URLEncodedScheme, host, URLEncodedHost, port, user; @dynamic URLEncodedUser, password, URLEncodedPassword, path, URLEncodedPath; @dynamic pathComponents, query, URLEncodedQuery, queryDictionary, fragment; @dynamic URLEncodedFragment; + (instancetype)URL |
︙ | ︙ | |||
55 56 57 58 59 60 61 | } - (void)setURLEncodedScheme: (OFString *)URLEncodedScheme { OFString *old; if (URLEncodedScheme != nil) | | | | | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | } - (void)setURLEncodedScheme: (OFString *)URLEncodedScheme { OFString *old; if (URLEncodedScheme != nil) OFURLVerifyIsEscaped(URLEncodedScheme, [OFCharacterSet URLSchemeAllowedCharacterSet]); old = _URLEncodedScheme; _URLEncodedScheme = [URLEncodedScheme copy]; [old release]; } - (void)setHost: (OFString *)host { void *pool = objc_autoreleasePoolPush(); OFString *old = _URLEncodedHost; if (OFURLIsIPv6Host(host)) _URLEncodedHost = [[OFString alloc] initWithFormat: @"[%@]", host]; else _URLEncodedHost = [[host stringByURLEncodingWithAllowedCharacters: [OFCharacterSet URLHostAllowedCharacterSet]] copy]; [old release]; objc_autoreleasePoolPop(pool); } - (void)setURLEncodedHost: (OFString *)URLEncodedHost { OFString *old; if ([URLEncodedHost hasPrefix: @"["] && [URLEncodedHost hasSuffix: @"]"]) { if (!OFURLIsIPv6Host([URLEncodedHost substringWithRange: OFRangeMake(1, URLEncodedHost.length - 2)])) @throw [OFInvalidFormatException exception]; } else if (URLEncodedHost != nil) OFURLVerifyIsEscaped(URLEncodedHost, [OFCharacterSet URLHostAllowedCharacterSet]); old = _URLEncodedHost; _URLEncodedHost = [URLEncodedHost copy]; [old release]; } |
︙ | ︙ | |||
124 125 126 127 128 129 130 | } - (void)setURLEncodedUser: (OFString *)URLEncodedUser { OFString *old; if (URLEncodedUser != nil) | | | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | } - (void)setURLEncodedUser: (OFString *)URLEncodedUser { OFString *old; if (URLEncodedUser != nil) OFURLVerifyIsEscaped(URLEncodedUser, [OFCharacterSet URLUserAllowedCharacterSet]); old = _URLEncodedUser; _URLEncodedUser = [URLEncodedUser copy]; [old release]; } |
︙ | ︙ | |||
151 152 153 154 155 156 157 | } - (void)setURLEncodedPassword: (OFString *)URLEncodedPassword { OFString *old; if (URLEncodedPassword != nil) | | | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | } - (void)setURLEncodedPassword: (OFString *)URLEncodedPassword { OFString *old; if (URLEncodedPassword != nil) OFURLVerifyIsEscaped(URLEncodedPassword, [OFCharacterSet URLPasswordAllowedCharacterSet]); old = _URLEncodedPassword; _URLEncodedPassword = [URLEncodedPassword copy]; [old release]; } |
︙ | ︙ | |||
177 178 179 180 181 182 183 | } - (void)setURLEncodedPath: (OFString *)URLEncodedPath { OFString *old; if (URLEncodedPath != nil) | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | } - (void)setURLEncodedPath: (OFString *)URLEncodedPath { OFString *old; if (URLEncodedPath != nil) OFURLVerifyIsEscaped(URLEncodedPath, [OFCharacterSet URLPathAllowedCharacterSet]); old = _URLEncodedPath; _URLEncodedPath = [URLEncodedPath copy]; [old release]; } |
︙ | ︙ | |||
223 224 225 226 227 228 229 | } - (void)setURLEncodedQuery: (OFString *)URLEncodedQuery { OFString *old; if (URLEncodedQuery != nil) | | | 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | } - (void)setURLEncodedQuery: (OFString *)URLEncodedQuery { OFString *old; if (URLEncodedQuery != nil) OFURLVerifyIsEscaped(URLEncodedQuery, [OFCharacterSet URLQueryAllowedCharacterSet]); old = _URLEncodedQuery; _URLEncodedQuery = [URLEncodedQuery copy]; [old release]; } |
︙ | ︙ | |||
291 292 293 294 295 296 297 | } - (void)setURLEncodedFragment: (OFString *)URLEncodedFragment { OFString *old; if (URLEncodedFragment != nil) | | | < | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | } - (void)setURLEncodedFragment: (OFString *)URLEncodedFragment { OFString *old; if (URLEncodedFragment != nil) OFURLVerifyIsEscaped(URLEncodedFragment, [OFCharacterSet URLFragmentAllowedCharacterSet]); old = _URLEncodedFragment; _URLEncodedFragment = [URLEncodedFragment copy]; [old release]; } - (id)copy { OFMutableURL *copy = [self mutableCopy]; [copy makeImmutable]; return copy; } - (void)appendPathComponent: (OFString *)component { [self appendPathComponent: component isDirectory: false]; #ifdef OF_HAVE_FILES if ([_URLEncodedScheme isEqual: @"file"] && ![_URLEncodedPath hasSuffix: @"/"] && [[OFFileManager defaultManager] directoryExistsAtURL: self]) { void *pool = objc_autoreleasePoolPush(); OFString *path = [_URLEncodedPath |
︙ | ︙ | |||
403 404 405 406 407 408 409 | done = false; break; } if ([current isEqual: @".."] && parent != nil && ![parent isEqual: @".."]) { [array removeObjectsInRange: | | | < | 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | done = false; break; } if ([current isEqual: @".."] && parent != nil && ![parent isEqual: @".."]) { [array removeObjectsInRange: OFRangeMake(i - 1, 2)]; done = false; break; } } } [array insertObject: @"" atIndex: 0]; if (endsWithEmpty) [array addObject: @""]; path = [array componentsJoinedByString: @"/"]; if (path.length == 0) path = @"/"; |
︙ | ︙ |
Modified src/OFMutableUTF8String.h from [b6241cfb40] to [681d1d0ba4].
1 | /* | < < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFMutableString.h" #import "OFUTF8String.h" OF_ASSUME_NONNULL_BEGIN @interface OFMutableUTF8String: OFMutableString { struct OFUTF8StringIvars *restrict _s; struct OFUTF8StringIvars _storage; } @end OF_ASSUME_NONNULL_END |
Modified src/OFMutableUTF8String.m from [cb57991be9] to [e069c57766].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <stdarg.h> #include <stdlib.h> #include <string.h> #include <assert.h> #import "OFMutableUTF8String.h" #import "OFString.h" #import "OFUTF8String.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" | > < < | | | | < < | | < | | < > | | | | | | | | < | | | | | | | | | | | | | | | > | < | | | | | | < | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | #include <stdarg.h> #include <stdlib.h> #include <string.h> #include <assert.h> #import "OFMutableUTF8String.h" #import "OFASPrintF.h" #import "OFString.h" #import "OFUTF8String.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "unicode.h" @implementation OFMutableUTF8String + (void)initialize { if (self == [OFMutableUTF8String class]) [self inheritMethodsFromClass: [OFUTF8String class]]; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone { self = [self initWithUTF8String: UTF8String]; if (freeWhenDone) OFFreeMemory(UTF8String); return self; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { self = [self initWithUTF8String: UTF8String length: UTF8StringLength]; if (freeWhenDone) OFFreeMemory(UTF8String); return self; } #ifdef OF_HAVE_UNICODE_TABLES - (void)of_convertWithWordStartTable: (const OFUnichar *const [])startTable wordMiddleTable: (const OFUnichar *const [])middleTable wordStartTableSize: (size_t)startTableSize wordMiddleTableSize: (size_t)middleTableSize { OFUnichar *unicodeString; size_t unicodeLen, newCStringLength; size_t i, j; char *newCString; bool isStart = true; if (!_s->isUTF8) { uint8_t t; const OFUnichar *const *table; assert(startTableSize >= 1 && middleTableSize >= 1); _s->hasHash = false; for (i = 0; i < _s->cStringLength; i++) { if (isStart) table = startTable; else table = middleTable; isStart = OFASCIIIsSpace(_s->cString[i]); if ((t = table[0][(uint8_t)_s->cString[i]]) != 0) _s->cString[i] = t; } return; } unicodeLen = self.length; unicodeString = OFAllocMemory(unicodeLen, sizeof(OFUnichar)); i = j = 0; newCStringLength = 0; while (i < _s->cStringLength) { const OFUnichar *const *table; size_t tableSize; OFUnichar c; ssize_t cLen; if (isStart) { table = startTable; tableSize = middleTableSize; } else { table = middleTable; tableSize = middleTableSize; } cLen = OFUTF8StringDecode(_s->cString + i, _s->cStringLength - i, &c); if (cLen <= 0 || c > 0x10FFFF) { OFFreeMemory(unicodeString); @throw [OFInvalidEncodingException exception]; } isStart = OFASCIIIsSpace(c); if (c >> 8 < tableSize) { OFUnichar tc = table[c >> 8][c & 0xFF]; if (tc) c = tc; } unicodeString[j++] = c; if (c < 0x80) newCStringLength++; else if (c < 0x800) newCStringLength += 2; else if (c < 0x10000) newCStringLength += 3; else if (c < 0x110000) newCStringLength += 4; else { OFFreeMemory(unicodeString); @throw [OFInvalidEncodingException exception]; } i += cLen; } @try { newCString = OFAllocMemory(newCStringLength + 1, 1); } @catch (id e) { OFFreeMemory(unicodeString); @throw e; } j = 0; for (i = 0; i < unicodeLen; i++) { size_t d; if ((d = OFUTF8StringEncode(unicodeString[i], newCString + j)) == 0) { OFFreeMemory(unicodeString); OFFreeMemory(newCString); @throw [OFInvalidEncodingException exception]; } j += d; } assert(j == newCStringLength); newCString[j] = 0; OFFreeMemory(unicodeString); OFFreeMemory(_s->cString); _s->hasHash = false; _s->cString = newCString; _s->cStringLength = newCStringLength; /* * Even though cStringLength can change, length cannot, therefore no * need to change it. */ } #endif - (void)setCharacter: (OFUnichar)character atIndex: (size_t)idx { char buffer[4]; OFUnichar c; size_t lenNew; ssize_t lenOld; if (_s->isUTF8) idx = OFUTF8StringIndexToPosition(_s->cString, idx, _s->cStringLength); if (idx >= _s->cStringLength) @throw [OFOutOfRangeException exception]; /* Shortcut if old and new character both are ASCII */ if (character < 0x80 && !(_s->cString[idx] & 0x80)) { _s->hasHash = false; _s->cString[idx] = character; return; } if ((lenNew = OFUTF8StringEncode(character, buffer)) == 0) @throw [OFInvalidEncodingException exception]; if ((lenOld = OFUTF8StringDecode(_s->cString + idx, _s->cStringLength - idx, &c)) <= 0) @throw [OFInvalidEncodingException exception]; _s->hasHash = false; if (lenNew == (size_t)lenOld) memcpy(_s->cString + idx, buffer, lenNew); else if (lenNew > (size_t)lenOld) { _s->cString = OFResizeMemory(_s->cString, _s->cStringLength - lenOld + lenNew + 1, 1); memmove(_s->cString + idx + lenNew, _s->cString + idx + lenOld, _s->cStringLength - idx - lenOld); memcpy(_s->cString + idx, buffer, lenNew); _s->cStringLength -= lenOld; _s->cStringLength += lenNew; |
︙ | ︙ | |||
252 253 254 255 256 257 258 | _s->cStringLength += lenNew; _s->cString[_s->cStringLength] = '\0'; if (character >= 0x80) _s->isUTF8 = true; @try { | | < | | | < | | | | < | | | | | | < | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | _s->cStringLength += lenNew; _s->cString[_s->cStringLength] = '\0'; if (character >= 0x80) _s->isUTF8 = true; @try { _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } } - (void)appendUTF8String: (const char *)UTF8String { size_t UTF8StringLength = strlen(UTF8String); size_t length; if (UTF8StringLength >= 3 && memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) { UTF8String += 3; UTF8StringLength -= 3; } switch (OFUTF8StringCheck(UTF8String, UTF8StringLength, &length)) { case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } _s->hasHash = false; _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + UTF8StringLength + 1, 1); memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength + 1); _s->cStringLength += UTF8StringLength; _s->length += length; } - (void)appendUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength { size_t length; if (UTF8StringLength >= 3 && memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) { UTF8String += 3; UTF8StringLength -= 3; } switch (OFUTF8StringCheck(UTF8String, UTF8StringLength, &length)) { case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } _s->hasHash = false; _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + UTF8StringLength + 1, 1); memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength); _s->cStringLength += UTF8StringLength; _s->length += length; _s->cString[_s->cStringLength] = 0; } - (void)appendCString: (const char *)cString encoding: (OFStringEncoding)encoding { [self appendCString: cString encoding: encoding length: strlen(cString)]; } - (void)appendCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength { if (encoding == OFStringEncodingUTF8) [self appendUTF8String: cString length: cStringLength]; else { void *pool = objc_autoreleasePoolPush(); [self appendString: [OFString stringWithCString: cString encoding: encoding length: cStringLength]]; |
︙ | ︙ | |||
358 359 360 361 362 363 364 | size_t UTF8StringLength; if (string == nil) @throw [OFInvalidArgumentException exception]; UTF8StringLength = string.UTF8StringLength; | | < | | | < | < | < | | | | | < | | < | | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | size_t UTF8StringLength; if (string == nil) @throw [OFInvalidArgumentException exception]; UTF8StringLength = string.UTF8StringLength; _s->hasHash = false; _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + UTF8StringLength + 1, 1); memcpy(_s->cString + _s->cStringLength, string.UTF8String, UTF8StringLength); _s->cStringLength += UTF8StringLength; _s->length += string.length; _s->cString[_s->cStringLength] = 0; if ([string isKindOfClass: [OFUTF8String class]] || [string isKindOfClass: [OFMutableUTF8String class]]) { if (((OFMutableUTF8String *)string)->_s->isUTF8) _s->isUTF8 = true; } else _s->isUTF8 = true; } - (void)appendCharacters: (const OFUnichar *)characters length: (size_t)length { char *tmp = OFAllocMemory((length * 4) + 1, 1); @try { size_t j = 0; bool isUTF8 = false; for (size_t i = 0; i < length; i++) { size_t len = OFUTF8StringEncode(characters[i], tmp + j); if (len == 0) @throw [OFInvalidEncodingException exception]; if (len > 1) isUTF8 = true; j += len; } tmp[j] = '\0'; _s->hasHash = false; _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + j + 1, 1); memcpy(_s->cString + _s->cStringLength, tmp, j + 1); _s->cStringLength += j; _s->length += length; if (isUTF8) _s->isUTF8 = true; } @finally { OFFreeMemory(tmp); } } - (void)appendFormat: (OFConstantString *)format arguments: (va_list)arguments { char *UTF8String; int UTF8StringLength; if (format == nil) @throw [OFInvalidArgumentException exception]; if ((UTF8StringLength = OFVASPrintF(&UTF8String, format.UTF8String, arguments)) == -1) @throw [OFInvalidFormatException exception]; @try { [self appendUTF8String: UTF8String length: UTF8StringLength]; } @finally { free(UTF8String); } } - (void)reverse { size_t i, j; _s->hasHash = false; /* We reverse all bytes and restore UTF-8 later, if necessary */ for (i = 0, j = _s->cStringLength - 1; i < _s->cStringLength / 2; i++, j--) { _s->cString[i] ^= _s->cString[j]; _s->cString[j] ^= _s->cString[i]; _s->cString[i] ^= _s->cString[j]; |
︙ | ︙ | |||
519 520 521 522 523 524 525 | } /* UTF-8 does not allow more than 4 bytes per character */ @throw [OFInvalidEncodingException exception]; } } | | < | | < | | | | | < | > | | | | < | > < | > | | | | < < | > | | < | | | | | | < | > | | < | > | | | < | > | 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 | } /* UTF-8 does not allow more than 4 bytes per character */ @throw [OFInvalidEncodingException exception]; } } - (void)insertString: (OFString *)string atIndex: (size_t)idx { size_t newCStringLength; if (idx > _s->length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) idx = OFUTF8StringIndexToPosition(_s->cString, idx, _s->cStringLength); newCStringLength = _s->cStringLength + string.UTF8StringLength; _s->hasHash = false; _s->cString = OFResizeMemory(_s->cString, newCStringLength + 1, 1); memmove(_s->cString + idx + string.UTF8StringLength, _s->cString + idx, _s->cStringLength - idx); memcpy(_s->cString + idx, string.UTF8String, string.UTF8StringLength); _s->cString[newCStringLength] = '\0'; _s->cStringLength = newCStringLength; _s->length += string.length; if ([string isKindOfClass: [OFUTF8String class]] || [string isKindOfClass: [OFMutableUTF8String class]]) { if (((OFMutableUTF8String *)string)->_s->isUTF8) _s->isUTF8 = true; } else _s->isUTF8 = true; } - (void)deleteCharactersInRange: (OFRange)range { size_t start = range.location; size_t end = range.location + range.length; if (range.length > SIZE_MAX - range.location || end > _s->length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) { start = OFUTF8StringIndexToPosition(_s->cString, start, _s->cStringLength); end = OFUTF8StringIndexToPosition(_s->cString, end, _s->cStringLength); } memmove(_s->cString + start, _s->cString + end, _s->cStringLength - end); _s->hasHash = false; _s->length -= range.length; _s->cStringLength -= end - start; _s->cString[_s->cStringLength] = 0; @try { _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } - (void)replaceCharactersInRange: (OFRange)range withString: (OFString *)replacement { size_t start = range.location; size_t end = range.location + range.length; size_t newCStringLength, newLength; if (replacement == nil) @throw [OFInvalidArgumentException exception]; if (range.length > SIZE_MAX - range.location || end > _s->length) @throw [OFOutOfRangeException exception]; newLength = _s->length - range.length + replacement.length; if (_s->isUTF8) { start = OFUTF8StringIndexToPosition(_s->cString, start, _s->cStringLength); end = OFUTF8StringIndexToPosition(_s->cString, end, _s->cStringLength); } newCStringLength = _s->cStringLength - (end - start) + replacement.UTF8StringLength; _s->hasHash = false; /* * If the new string is bigger, we need to resize it first so we can * memmove() the rest of the string to the end. * * We must not resize the string if the new string is smaller, because * then we can't memmove() the rest of the string forward as the rest is * lost due to the resize! */ if (newCStringLength > _s->cStringLength) _s->cString = OFResizeMemory(_s->cString, newCStringLength + 1, 1); memmove(_s->cString + start + replacement.UTF8StringLength, _s->cString + end, _s->cStringLength - end); memcpy(_s->cString + start, replacement.UTF8String, replacement.UTF8StringLength); _s->cString[newCStringLength] = '\0'; /* * If the new string is smaller, we can safely resize it now as we're * done with memmove(). */ if (newCStringLength < _s->cStringLength) _s->cString = OFResizeMemory(_s->cString, newCStringLength + 1, 1); _s->cStringLength = newCStringLength; _s->length = newLength; if ([replacement isKindOfClass: [OFUTF8String class]] || [replacement isKindOfClass: [OFMutableUTF8String class]]) { if (((OFMutableUTF8String *)replacement)->_s->isUTF8) _s->isUTF8 = true; } else _s->isUTF8 = true; } - (void)replaceOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (OFRange)range { const char *searchString = string.UTF8String; const char *replacementString = replacement.UTF8String; size_t searchLength = string.UTF8StringLength; size_t replacementLength = replacement.UTF8StringLength; size_t last, newCStringLength, newLength; char *newCString; if (string == nil || replacement == nil) @throw [OFInvalidArgumentException exception]; if (range.length > SIZE_MAX - range.location || range.location + range.length > self.length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) { range.location = OFUTF8StringIndexToPosition(_s->cString, range.location, _s->cStringLength); range.length = OFUTF8StringIndexToPosition( _s->cString + range.location, range.length, _s->cStringLength - range.location); } if (string.UTF8StringLength > range.length) return; newCString = NULL; newCStringLength = 0; newLength = _s->length; last = 0; for (size_t i = range.location; i <= range.length - searchLength; i++) { if (memcmp(_s->cString + i, searchString, searchLength) != 0) continue; @try { newCString = OFResizeMemory(newCString, newCStringLength + i - last + replacementLength + 1, 1); } @catch (id e) { OFFreeMemory(newCString); @throw e; } memcpy(newCString + newCStringLength, _s->cString + last, i - last); memcpy(newCString + newCStringLength + i - last, replacementString, replacementLength); newCStringLength += i - last + replacementLength; newLength = newLength - string.length + replacement.length; i += searchLength - 1; last = i + 1; } @try { newCString = OFResizeMemory(newCString, newCStringLength + _s->cStringLength - last + 1, 1); } @catch (id e) { OFFreeMemory(newCString); @throw e; } memcpy(newCString + newCStringLength, _s->cString + last, _s->cStringLength - last); newCStringLength += _s->cStringLength - last; newCString[newCStringLength] = 0; OFFreeMemory(_s->cString); _s->hasHash = false; _s->cString = newCString; _s->cStringLength = newCStringLength; _s->length = newLength; if ([replacement isKindOfClass: [OFUTF8String class]] || [replacement isKindOfClass: [OFMutableUTF8String class]]) { if (((OFMutableUTF8String *)replacement)->_s->isUTF8) _s->isUTF8 = true; } else _s->isUTF8 = true; } - (void)deleteLeadingWhitespaces { size_t i; for (i = 0; i < _s->cStringLength; i++) if (!OFASCIIIsSpace(_s->cString[i])) break; _s->hasHash = false; _s->cStringLength -= i; _s->length -= i; memmove(_s->cString, _s->cString + i, _s->cStringLength); _s->cString[_s->cStringLength] = '\0'; @try { _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } - (void)deleteTrailingWhitespaces { size_t d; char *p; _s->hasHash = false; d = 0; for (p = _s->cString + _s->cStringLength - 1; p >= _s->cString; p--) { if (!OFASCIIIsSpace(*p)) break; *p = '\0'; d++; } _s->cStringLength -= d; _s->length -= d; @try { _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } - (void)deleteEnclosingWhitespaces { size_t d, i; char *p; _s->hasHash = false; d = 0; for (p = _s->cString + _s->cStringLength - 1; p >= _s->cString; p--) { if (!OFASCIIIsSpace(*p)) break; *p = '\0'; d++; } _s->cStringLength -= d; _s->length -= d; for (i = 0; i < _s->cStringLength; i++) if (!OFASCIIIsSpace(_s->cString[i])) break; _s->cStringLength -= i; _s->length -= i; memmove(_s->cString, _s->cString + i, _s->cStringLength); _s->cString[_s->cStringLength] = '\0'; @try { _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't really care, as we only made it smaller */ } } - (void)makeImmutable { object_setClass(self, [OFUTF8String class]); } @end |
Modified src/OFMutableZIPArchiveEntry.h from [b1ed162368] to [7d57139a39].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
50 51 52 53 54 55 56 | @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFData *extraField; /** * @brief The version which made the entry. * * The lower 8 bits are the ZIP specification version.@n * The upper 8 bits are the attribute compatibility. | | | > | | > | | | | | | > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | @property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFData *extraField; /** * @brief The version which made the entry. * * The lower 8 bits are the ZIP specification version.@n * The upper 8 bits are the attribute compatibility. * See @ref OFZIPArchiveEntryAttributeCompatibility. */ @property (readwrite, nonatomic) OFZIPArchiveEntryAttributeCompatibility versionMadeBy; /** * @brief The minimum version required to extract the file. * * The lower 8 bits are the ZIP specification version.@n * The upper 8 bits are the attribute compatibility. * See @ref OFZIPArchiveEntryAttributeCompatibility. */ @property (readwrite, nonatomic) OFZIPArchiveEntryAttributeCompatibility minVersionNeeded; /** * @brief The last modification date of the entry's file. * * @note Due to limitations of the ZIP format, this has only 2 second precision. */ @property (readwrite, retain, nonatomic) OFDate *modificationDate; /** * @brief The compression method of the entry. * * Supported values are: * Value | Description * --------------------------------------------|--------------- * OFZIPArchiveEntryCompressionMethodNone | No compression * OFZIPArchiveEntryCompressionMethodDeflate | Deflate * OFZIPArchiveEntryCompressionMethodDeflate64 | Deflate64 * * Other values may be returned, but the file cannot be extracted then. */ @property (readwrite, nonatomic) OFZIPArchiveEntryCompressionMethod compressionMethod; /** * @brief The compressed size of the entry's file. */ @property (readwrite, nonatomic) uint64_t compressedSize; /** |
︙ | ︙ |
Modified src/OFMutableZIPArchiveEntry.m from [7972fcd174] to [bdaf9f4cc4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
31 32 33 34 35 36 37 | @dynamic modificationDate, compressionMethod, compressedSize, uncompressedSize; @dynamic CRC32, versionSpecificAttributes, generalPurposeBitFlag; @dynamic of_localFileHeaderOffset; - (id)copy { OFMutableZIPArchiveEntry *copy = [self mutableCopy]; | < < | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | @dynamic modificationDate, compressionMethod, compressedSize, uncompressedSize; @dynamic CRC32, versionSpecificAttributes, generalPurposeBitFlag; @dynamic of_localFileHeaderOffset; - (id)copy { OFMutableZIPArchiveEntry *copy = [self mutableCopy]; [copy makeImmutable]; return copy; } - (void)setFileName: (OFString *)fileName { void *pool = objc_autoreleasePoolPush(); OFString *old; |
︙ | ︙ | |||
85 86 87 88 89 90 91 | old = _extraField; _extraField = [extraField copy]; [old release]; objc_autoreleasePoolPop(pool); } | | > | > | > | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | old = _extraField; _extraField = [extraField copy]; [old release]; objc_autoreleasePoolPop(pool); } - (void)setVersionMadeBy: (OFZIPArchiveEntryAttributeCompatibility)versionMadeBy { _versionMadeBy = versionMadeBy; } - (void)setMinVersionNeeded: (OFZIPArchiveEntryAttributeCompatibility)minVersionNeeded { _minVersionNeeded = minVersionNeeded; } - (void)setModificationDate: (OFDate *)date { void *pool = objc_autoreleasePoolPush(); _lastModifiedFileDate = (((date.localYear - 1980) & 0xFF) << 9) | ((date.localMonthOfYear & 0x0F) << 5) | (date.localDayOfMonth & 0x1F); _lastModifiedFileTime = ((date.localHour & 0x1F) << 11) | ((date.localMinute & 0x3F) << 5) | ((date.second >> 1) & 0x0F); objc_autoreleasePoolPop(pool); } - (void)setCompressionMethod: (OFZIPArchiveEntryCompressionMethod)compressionMethod { _compressionMethod = compressionMethod; } - (void)setCompressedSize: (uint64_t)compressedSize { _compressedSize = compressedSize; |
︙ | ︙ |
Modified src/OFMutex.h from [bb9b8d8163] to [f277ea27da].
1 | /* | < < | < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFLocking.h" #import "OFPlainMutex.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFMutex OFMutex.h ObjFW/OFMutex.h * * @brief A class for creating mutual exclusions. */ @interface OFMutex: OFObject <OFLocking> { OFPlainMutex _mutex; bool _initialized; OFString *_Nullable _name; OF_RESERVE_IVARS(OFMutex, 4) } /** * @brief Creates a new mutex. |
︙ | ︙ |
Modified src/OFMutex.m from [2c5bdb0793] to [91291c7344].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
35 36 37 38 39 40 41 | return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; | | > | > | | > > | > | > | | > | > | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; if (OFPlainMutexNew(&_mutex) != 0) { Class c = self.class; [self release]; @throw [OFInitializationFailedException exceptionWithClass: c]; } _initialized = true; return self; } - (void)dealloc { if (_initialized) { int error = OFPlainMutexFree(&_mutex); if (error != 0) { OFEnsure(error == EBUSY); @throw [OFStillLockedException exceptionWithLock: self]; } } [_name release]; [super dealloc]; } - (void)lock { int error = OFPlainMutexLock(&_mutex); if (error != 0) @throw [OFLockFailedException exceptionWithLock: self errNo: error]; } - (bool)tryLock { int error = OFPlainMutexTryLock(&_mutex); if (error != 0) { if (error == EBUSY) return false; else @throw [OFLockFailedException exceptionWithLock: self errNo: error]; } return true; } - (void)unlock { int error = OFPlainMutexUnlock(&_mutex); if (error != 0) @throw [OFUnlockFailedException exceptionWithLock: self errNo: error]; } - (OFString *)description { if (_name == nil) return super.description; return [OFString stringWithFormat: @"<%@: %@>", self.className, _name]; } @end |
Modified src/OFNonretainedObjectValue.h from [1970a050e9] to [3bd7c9c6b7].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 | OF_ASSUME_NONNULL_BEGIN @interface OFNonretainedObjectValue: OFValue { id _object; } @end OF_ASSUME_NONNULL_END | > > | 17 18 19 20 21 22 23 24 25 26 27 28 | OF_ASSUME_NONNULL_BEGIN @interface OFNonretainedObjectValue: OFValue { id _object; } - (instancetype)initWithNonretainedObject: (id)object; @end OF_ASSUME_NONNULL_END |
Modified src/OFNonretainedObjectValue.m from [ecf9f83c85] to [93108c2968].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
33 34 35 36 37 38 39 | } - (const char *)objCType { return @encode(id); } | | < | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | } - (const char *)objCType { return @encode(id); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_object)) @throw [OFOutOfRangeException exception]; memcpy(value, &_object, sizeof(_object)); } - (void *)pointerValue { return _object; } @end |
Added src/OFNotification.h version [de7bff6c2a].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFConstantString; @class OFDictionary OF_GENERIC(KeyType, ObjectType); /** * @brief A name for a notification. */ typedef OFConstantString *OFNotificationName; /** * @class OFNotification OFNotification.h ObjFW/OFNotification.h * * @brief A class to represent a notification for or from * @ref OFNotificationCenter. */ OF_SUBCLASSING_RESTRICTED @interface OFNotification: OFObject <OFCopying> { OFNotificationName _name; id _Nullable _object; OFDictionary *_Nullable _userInfo; } /** * @brief The name of the notification. */ @property (readonly, nonatomic) OFNotificationName name; /** * @brief The object of the notification. This is commonly the sender of the * notification. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) id object; /** * @brief Additional information about the notification. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFDictionary *userInfo; /** * @brief Creates a new notification with the specified name and object. * * @param name The name for the notification * @param object The object for the notification. This is commonly the sender * of the notification. * @return A new, autoreleased OFNotification */ + (instancetype)notificationWithName: (OFNotificationName)name object: (nullable id)object; /** * @brief Creates a new notification with the specified name, object and * additional information. * * @param name The name for the notification * @param object The object for the notification. This is commonly the sender * of the notification. * @param userInfo Additional information for the notification * @return A new, autoreleased OFNotification */ + (instancetype)notificationWithName: (OFNotificationName)name object: (nullable id)object userInfo: (nullable OFDictionary *)userInfo; /** * @brief Initializes an already allocated notification with the specified * name and object. * * @param name The name for the notification * @param object The object for the notification. This is commonly the sender * of the notification. * @return An initialized OFNotification */ - (instancetype)initWithName: (OFNotificationName)name object: (nullable id)object; /** * @brief Initializes an already allocated notification with the specified * name, object and additional information. * * @param name The name for the notification * @param object The object for the notification. This is commonly the sender * of the notification. * @param userInfo Additional information for the notification * @return An initialized OFNotification */ - (instancetype)initWithName: (OFNotificationName)name object: (nullable id)object userInfo: (nullable OFDictionary *)userInfo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Added src/OFNotification.m version [d51e2a4110].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFNotification.h" #import "OFDictionary.h" #import "OFString.h" @implementation OFNotification @synthesize name = _name, object = _object, userInfo = _userInfo; + (instancetype)notificationWithName: (OFNotificationName)name object: (id)object { return [[[self alloc] initWithName: name object: object] autorelease]; } + (instancetype)notificationWithName: (OFNotificationName)name object: (id)object userInfo: (OFDictionary *)userInfo { return [[[self alloc] initWithName: name object: object userInfo: userInfo] autorelease]; } - (instancetype)initWithName: (OFNotificationName)name object: (id)object { return [self initWithName: name object: object userInfo: nil]; } - (instancetype)initWithName: (OFNotificationName)name object: (id)object userInfo: (OFDictionary *)userInfo { self = [super init]; @try { _name = [name copy]; _object = [object retain]; _userInfo = [userInfo copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_name release]; [_object release]; [_userInfo release]; [super dealloc]; } - (id)copy { return [self retain]; } @end |
Added src/OFNotificationCenter.h version [6d89a35135].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFNotification.h" OF_ASSUME_NONNULL_BEGIN @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); #ifdef OF_HAVE_THREADS @class OFMutex; #endif @class OFNotificationCenterHandle; #ifdef OF_HAVE_BLOCKS /** * @brief A block which is called when a notification has been posted. * * @param notification The notification that has been posted */ typedef void (^OFNotificationCenterBlock)(OFNotification *notification); #endif /** * @class OFNotificationCenter OFNotificationCenter.h \ * ObjFW/OFNotificationCenter.h * * @brief A class to send and register for notifications. */ @interface OFNotificationCenter: OFObject { #ifdef OF_HAVE_THREADS OFMutex *_mutex; #endif OFMutableDictionary *_handles; OF_RESERVE_IVARS(OFNotificationCenter, 4) } #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) OFNotificationCenter *defaultCenter; #endif /** * @brief Returns the default notification center. */ + (OFNotificationCenter *)defaultCenter; /** * @brief Adds an observer for the specified notification and object. * * @param observer The object that should receive notifications * @param selector The selector to call on the observer on notifications. The * method must take exactly one object of type @ref * OFNotification. * @param name The name of the notification to observe * @param object The object that should be sending the notification, or `nil` * if the object should be ignored to determine what * notifications to deliver */ - (void)addObserver: (id)observer selector: (SEL)selector name: (OFNotificationName)name object: (nullable id)object; /** * @brief Removes an observer. All parameters must match those used with * @ref addObserver:selector:name:object:. * * @param observer The observer that was specified when adding the observer * @param selector The selector that was specified when adding the observer * @param name The name that was specified when adding the observer * @param object The object that was specified when adding the observer */ - (void)removeObserver: (id)observer selector: (SEL)selector name: (OFNotificationName)name object: (nullable id)object; #ifdef OF_HAVE_BLOCKS /** * @brief Adds an observer for the specified notification and object. * * To remove the observer again, use @ref removeObserver:. * * @param name The name of the notification to observe * @param object The object that should be sending the notification, or `nil` * if the object should be ignored to determine what * notifications to deliver * @param block The block to handle notifications * @return An opaque object to remove the observer again */ - (OFNotificationCenterHandle *) addObserverForName: (OFNotificationName)name object: (nullable id)object usingBlock: (OFNotificationCenterBlock)block; /** * @brief Removes an observer. The specified observer must be one returned by * @ref addObserver:selector:name:object:. * * @param observer The object that was returned when adding the observer */ - (void)removeObserver: (OFNotificationCenterHandle *)observer; #endif /** * @brief Posts the specified notification. * * @param notification The notification to post */ - (void)postNotification: (OFNotification *)notification; /** * @brief Posts a notification with the specified name and object. * * @param name The name for the notification * @param object The object for the notification */ - (void)postNotificationName: (OFNotificationName)name object: (nullable id)object; /** * @brief Posts a notification with the specified name, object and additional * information. * * @param name The name for the notification * @param object The object for the notification * @param userInfo Additional information for the notification */ - (void)postNotificationName: (OFNotificationName)name object: (nullable id)object userInfo: (nullable OFDictionary *)userInfo; @end OF_ASSUME_NONNULL_END |
Added src/OFNotificationCenter.m version [3332a25cc3].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFNotificationCenter.h" #import "OFArray.h" #import "OFDictionary.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFSet.h" #import "OFString.h" #import "OFInvalidArgumentException.h" @interface OFDefaultNotificationCenter: OFNotificationCenter @end @interface OFNotificationCenterHandle: OFObject { @public OFNotificationName _name; id _observer; SEL _selector; unsigned long _selectorHash; #ifdef OF_HAVE_BLOCKS OFNotificationCenterBlock _block; #endif id _object; } - (instancetype)initWithName: (OFNotificationName)name observer: (id)observer selector: (SEL)selector object: (id)object; #ifdef OF_HAVE_BLOCKS - (instancetype)initWithName: (OFNotificationName)name object: (id)object block: (OFNotificationCenterBlock)block; #endif @end static OFNotificationCenter *defaultCenter; @implementation OFNotificationCenterHandle - (instancetype)initWithName: (OFNotificationName)name observer: (id)observer selector: (SEL)selector object: (id)object { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); _name = [name copy]; _observer = [observer retain]; _selector = selector; _object = [object retain]; _selectorHash = [[OFString stringWithUTF8String: sel_getName(_selector)] hash]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } #ifdef OF_HAVE_BLOCKS - (instancetype)initWithName: (OFNotificationName)name object: (id)object block: (OFNotificationCenterBlock)block { self = [super init]; @try { _name = [name copy]; _object = [object retain]; _block = [block copy]; } @catch (id e) { [self release]; @throw e; } return self; } #endif - (void)dealloc { [_name release]; [_observer release]; [_object release]; #ifdef OF_HAVE_BLOCKS [_block release]; #endif [super dealloc]; } - (bool)isEqual: (OFNotificationCenterHandle *)handle { if (![handle isKindOfClass: [OFNotificationCenterHandle class]]) return false; if (![handle->_name isEqual: _name]) return false; if (handle->_observer != _observer && ![handle->_observer isEqual: _observer]) return false; if (handle->_selector != _selector && !sel_isEqual(handle->_selector, _selector)) return false; #ifdef OF_HAVE_BLOCKS if (handle->_block != _block) return false; #endif if (handle->_object != _object && ![handle->_object isEqual: _object]) return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddHash(&hash, [_observer hash]); OFHashAddHash(&hash, _selectorHash); #ifdef OF_HAVE_BLOCKS if (_block != NULL) OFHashAddHash(&hash, (unsigned long)(uintptr_t)_block); #endif OFHashAddHash(&hash, [_object hash]); OFHashFinalize(&hash); return hash; } @end @implementation OFNotificationCenter + (void)initialize { if (self != [OFNotificationCenter class]) return; defaultCenter = [[OFDefaultNotificationCenter alloc] init]; } + (OFNotificationCenter *)defaultCenter { return defaultCenter; } - (instancetype)init { self = [super init]; @try { #ifdef OF_HAVE_THREADS _mutex = [[OFMutex alloc] init]; #endif _handles = [[OFMutableDictionary alloc] init]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { #ifdef OF_HAVE_THREADS [_mutex release]; #endif [_handles release]; [super dealloc]; } - (void)of_addObserver: (OFNotificationCenterHandle *)handle { #ifdef OF_HAVE_THREADS [_mutex lock]; @try { #endif OFMutableSet *handlesForName = [_handles objectForKey: handle->_name]; if (handlesForName == nil) { handlesForName = [OFMutableSet set]; [_handles setObject: handlesForName forKey: handle->_name]; } [handlesForName addObject: handle]; #ifdef OF_HAVE_THREADS } @finally { [_mutex unlock]; } #endif } - (void)addObserver: (id)observer selector: (SEL)selector name: (OFNotificationName)name object: (id)object { void *pool = objc_autoreleasePoolPush(); [self of_addObserver: [[[OFNotificationCenterHandle alloc] initWithName: name observer: observer selector: selector object: object] autorelease]]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (OFNotificationCenterHandle *) addObserverForName: (OFNotificationName)name object: (id)object usingBlock: (OFNotificationCenterBlock)block { void *pool = objc_autoreleasePoolPush(); OFNotificationCenterHandle *handle = [[[OFNotificationCenterHandle alloc] initWithName: name object: object block: block] autorelease]; [self of_addObserver: handle]; [handle retain]; objc_autoreleasePoolPop(pool); return [handle autorelease]; } #endif - (void)removeObserver: (OFNotificationCenterHandle *)handle { void *pool = objc_autoreleasePoolPush(); /* {} required to avoid -Wmisleading-indentation false positive. */ if (![handle isKindOfClass: [OFNotificationCenterHandle class]]) { @throw [OFInvalidArgumentException exception]; } #ifdef OF_HAVE_THREADS [_mutex lock]; @try { #endif OFNotificationName name = [[handle->_name copy] autorelease]; OFMutableSet *handlesForName = [_handles objectForKey: name]; [handlesForName removeObject: handle]; if (handlesForName.count == 0) [_handles removeObjectForKey: name]; #ifdef OF_HAVE_THREADS } @finally { [_mutex unlock]; } #endif objc_autoreleasePoolPop(pool); } - (void)removeObserver: (id)observer selector: (SEL)selector name: (OFNotificationName)name object: (id)object { void *pool = objc_autoreleasePoolPush(); [self removeObserver: [[[OFNotificationCenterHandle alloc] initWithName: name observer: observer selector: selector object: object] autorelease]]; objc_autoreleasePoolPop(pool); } - (void)postNotification: (OFNotification *)notification { void *pool = objc_autoreleasePoolPush(); OFMutableArray *matchedHandles = [OFMutableArray array]; #ifdef OF_HAVE_THREADS [_mutex lock]; @try { #endif for (OFNotificationCenterHandle *handle in [_handles objectForKey: notification.name]) if (handle->_object == nil || handle->_object == notification.object) [matchedHandles addObject: handle]; #ifdef OF_HAVE_THREADS } @finally { [_mutex unlock]; } #endif for (OFNotificationCenterHandle *handle in matchedHandles) { #ifdef OF_HAVE_BLOCKS if (handle->_block != NULL) handle->_block(notification); else { #endif void (*callback)(id, SEL, OFNotification *) = (void (*)(id, SEL, OFNotification *)) [handle->_observer methodForSelector: handle->_selector]; callback(handle->_observer, handle->_selector, notification); #ifdef OF_HAVE_BLOCKS } #endif } objc_autoreleasePoolPop(pool); } - (void)postNotificationName: (OFNotificationName)name object: (nullable id)object { [self postNotificationName: name object: object userInfo: nil]; } - (void)postNotificationName: (OFNotificationName)name object: (nullable id)object userInfo: (nullable OFDictionary *)userInfo { void *pool = objc_autoreleasePoolPush(); [self postNotification: [OFNotification notificationWithName: name object: object userInfo: userInfo]]; objc_autoreleasePoolPop(pool); } @end @implementation OFDefaultNotificationCenter - (instancetype)autorelease { return self; } - (instancetype)retain { return self; } - (void)release { } - (unsigned int)retainCount { return OFMaxRetainCount; } @end |
Modified src/OFNull.h from [8747bb1b27] to [787aabc24c].
1 | /* | < < | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFJSONRepresentation.h" #import "OFMessagePackRepresentation.h" #import "OFSerialization.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFNull OFNull.h ObjFW/OFNull.h * * @brief A class for representing null values in collections. */ OF_SUBCLASSING_RESTRICTED @interface OFNull: OFObject <OFCopying, OFSerialization, OFJSONRepresentation, OFMessagePackRepresentation> /** * @brief Returns an OFNull singleton. * * @return An OFNull singleton */ + (OFNull *)null; @end OF_ASSUME_NONNULL_END |
Modified src/OFNull.m from [43e1244281] to [bf841d1a2e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | #import "OFString.h" #import "OFXMLElement.h" #import "OFData.h" #import "OFInvalidArgumentException.h" @interface OFNull () | | > | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #import "OFString.h" #import "OFXMLElement.h" #import "OFData.h" #import "OFInvalidArgumentException.h" @interface OFNull () - (OFString *) of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options depth: (size_t)depth; @end static OFNull *null = nil; @implementation OFNull + (void)initialize { |
︙ | ︙ | |||
47 48 49 50 51 52 53 | void *pool; [self release]; pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | void *pool; [self release]; pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; objc_autoreleasePoolPop(pool); return [OFNull null]; } |
︙ | ︙ | |||
71 72 73 74 75 76 77 | - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className | | | < | > | < | > < | < < < < < < < < < | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } - (OFString *)JSONRepresentation { return [self of_JSONRepresentationWithOptions: 0 depth: 0]; } - (OFString *)JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options { return [self of_JSONRepresentationWithOptions: options depth: 0]; } - (OFString *) of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options depth: (size_t)depth { return @"null"; } - (OFData *)messagePackRepresentation { uint8_t type = 0xC0; return [OFData dataWithItems: &type count: 1]; } - (instancetype)autorelease { return self; } - (instancetype)retain { return self; } - (void)release { } - (unsigned int)retainCount { return OFMaxRetainCount; } - (void)dealloc { OF_DEALLOC_UNSUPPORTED } @end |
Modified src/OFNumber.h from [028df04d4c] to [eff21822aa].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
44 45 46 47 48 49 50 | */ #ifndef OF_NUMBER_M OF_SUBCLASSING_RESTRICTED #endif @interface OFNumber: OFValue <OFComparing, OFSerialization, OFJSONRepresentation, OFMessagePackRepresentation> { | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | */ #ifndef OF_NUMBER_M OF_SUBCLASSING_RESTRICTED #endif @interface OFNumber: OFValue <OFComparing, OFSerialization, OFJSONRepresentation, OFMessagePackRepresentation> { union { double float_; long long signed_; unsigned long long unsigned_; } _value; const char *_typeEncoding; } |
︙ | ︙ | |||
122 123 124 125 126 127 128 | @property (readonly, nonatomic) double doubleValue; /** * @brief The OFNumber as a string. */ @property (readonly, nonatomic) OFString *stringValue; | < | | | | < | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | @property (readonly, nonatomic) double doubleValue; /** * @brief The OFNumber as a string. */ @property (readonly, nonatomic) OFString *stringValue; + (instancetype)valueWithBytes: (const void *)bytes objCType: (const char *)objCType OF_UNAVAILABLE; + (instancetype)valueWithPointer: (const void *)pointer OF_UNAVAILABLE; + (instancetype)valueWithNonretainedObject: (id)object OF_UNAVAILABLE; + (instancetype)valueWithRange: (OFRange)range OF_UNAVAILABLE; + (instancetype)valueWithPoint: (OFPoint)point OF_UNAVAILABLE; + (instancetype)valueWithSize: (OFSize)size OF_UNAVAILABLE; + (instancetype)valueWithRect: (OFRect)rect OF_UNAVAILABLE; /** * @brief Creates a new OFNumber with the specified `bool`. * * @param value The `bool` value which the OFNumber should contain * @return A new autoreleased OFNumber */ |
︙ | ︙ | |||
238 239 240 241 242 243 244 | * * @param value The `double` value which the OFNumber should contain * @return A new autoreleased OFNumber */ + (instancetype)numberWithDouble: (double)value; - (instancetype)init OF_UNAVAILABLE; | < < < < < < < < | 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | * * @param value The `double` value which the OFNumber should contain * @return A new autoreleased OFNumber */ + (instancetype)numberWithDouble: (double)value; - (instancetype)init OF_UNAVAILABLE; - (instancetype)initWithBytes: (const void *)bytes objCType: (const char *)objCType OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFNumber with the specified `bool`. * * @param value The `bool` value which the OFNumber should contain * @return An initialized OFNumber */ |
︙ | ︙ | |||
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 | /** * @brief Initializes an already allocated OFNumber with the specified `double`. * * @param value The `double` value which the OFNumber should contain * @return An initialized OFNumber */ - (instancetype)initWithDouble: (double)value; @end OF_ASSUME_NONNULL_END #if !defined(NSINTEGER_DEFINED) && !__has_feature(modules) /* Required for number literals to work */ @compatibility_alias NSNumber OFNumber; #endif | > > > > > > > > | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | /** * @brief Initializes an already allocated OFNumber with the specified `double`. * * @param value The `double` value which the OFNumber should contain * @return An initialized OFNumber */ - (instancetype)initWithDouble: (double)value; /** * @brief Compares the number to another number. * * @param number The number to compare the number to * @return The result of the comparison */ - (OFComparisonResult)compare: (OFNumber *)number; @end OF_ASSUME_NONNULL_END #if !defined(NSINTEGER_DEFINED) && !__has_feature(modules) /* Required for number literals to work */ @compatibility_alias NSNumber OFNumber; #endif |
Modified src/OFNumber.m from [80a9f3f337] to [fd08ff8e66].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" @interface OFNumber () + (instancetype)of_alloc; | | > | | | | | | | | | | | | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" @interface OFNumber () + (instancetype)of_alloc; - (OFString *) of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options depth: (size_t)depth; @end @interface OFNumberPlaceholder: OFNumber @end @interface OFNumberSingleton: OFNumber @end #ifdef OF_OBJFW_RUNTIME enum Tag { tagChar, tagShort, tagInt, tagLong, tagLongLong, tagUnsignedChar, tagUnsignedShort, tagUnsignedInt, tagUnsignedLong, tagUnsignedLongLong, }; static const uint_fast8_t tagBits = 4; static const uintptr_t tagMask = 0xF; @interface OFTaggedPointerNumber: OFNumberSingleton @end #endif static struct { Class isa; |
︙ | ︙ | |||
148 149 150 151 152 153 154 | } } @implementation OFNumberPlaceholder - (instancetype)initWithBool: (bool)value { if (value) { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | } } @implementation OFNumberPlaceholder - (instancetype)initWithBool: (bool)value { if (value) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, trueNumberInit); return (id)trueNumber; } else { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, falseNumberInit); return (id)falseNumber; } } #ifdef __clang__ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" #endif - (instancetype)initWithChar: (signed char)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, charZeroNumberInit); return (id)charZeroNumber; #ifdef OF_OBJFW_RUNTIME } else if ((unsigned char)value <= (UINTPTR_MAX >> tagBits)) { id ret = objc_createTaggedPointer(numberTag, ((uintptr_t)(unsigned char)value << tagBits) | tagChar); if (ret != nil) return ret; #endif } return (id)[[OFNumber of_alloc] initWithChar: value]; } - (instancetype)initWithShort: (short)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, shortZeroNumberInit); return (id)shortZeroNumber; #ifdef OF_OBJFW_RUNTIME } else if ((unsigned short)value <= (UINTPTR_MAX >> tagBits)) { id ret = objc_createTaggedPointer(numberTag, ((uintptr_t)(unsigned short)value << tagBits) | tagShort); if (ret != nil) return ret; #endif } return (id)[[OFNumber of_alloc] initWithShort: value]; } - (instancetype)initWithInt: (int)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, intZeroNumberInit); return (id)intZeroNumber; #ifdef OF_OBJFW_RUNTIME } else if ((unsigned int)value <= (UINTPTR_MAX >> tagBits)) { id ret = objc_createTaggedPointer(numberTag, ((uintptr_t)(unsigned int)value << tagBits) | tagInt); if (ret != nil) return ret; #endif } return (id)[[OFNumber of_alloc] initWithInt: value]; } - (instancetype)initWithLong: (long)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, longZeroNumberInit); return (id)longZeroNumber; #ifdef OF_OBJFW_RUNTIME } else if ((unsigned long)value <= (UINTPTR_MAX >> tagBits)) { id ret = objc_createTaggedPointer(numberTag, ((uintptr_t)(unsigned long)value << tagBits) | tagLong); if (ret != nil) return ret; #endif } return (id)[[OFNumber of_alloc] initWithLong: value]; } - (instancetype)initWithLongLong: (long long)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, longLongZeroNumberInit); return (id)longLongZeroNumber; #ifdef OF_OBJFW_RUNTIME } else if ((unsigned long long)value <= (UINTPTR_MAX >> tagBits)) { id ret = objc_createTaggedPointer(numberTag, ((uintptr_t)(unsigned long long)value << tagBits) | tagLongLong); if (ret != nil) return ret; #endif } return (id)[[OFNumber of_alloc] initWithLongLong: value]; } - (instancetype)initWithUnsignedChar: (unsigned char)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, unsignedCharZeroNumberInit); return (id)unsignedCharZeroNumber; #ifdef OF_OBJFW_RUNTIME } else if (value <= (UINTPTR_MAX >> tagBits)) { id ret = objc_createTaggedPointer(numberTag, ((uintptr_t)value << tagBits) | tagUnsignedChar); if (ret != nil) return ret; #endif } return (id)[[OFNumber of_alloc] initWithUnsignedChar: value]; } - (instancetype)initWithUnsignedShort: (unsigned short)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, unsignedShortZeroNumberInit); return (id)unsignedShortZeroNumber; #ifdef OF_OBJFW_RUNTIME } else if (value <= (UINTPTR_MAX >> tagBits)) { id ret = objc_createTaggedPointer(numberTag, ((uintptr_t)value << tagBits) | tagUnsignedShort); if (ret != nil) return ret; #endif } return (id)[[OFNumber of_alloc] initWithUnsignedShort: value]; } - (instancetype)initWithUnsignedInt: (unsigned int)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, unsignedIntZeroNumberInit); return (id)unsignedIntZeroNumber; #ifdef OF_OBJFW_RUNTIME } else if (value <= (UINTPTR_MAX >> tagBits)) { id ret = objc_createTaggedPointer(numberTag, ((uintptr_t)value << tagBits) | tagUnsignedInt); if (ret != nil) return ret; #endif } return (id)[[OFNumber of_alloc] initWithUnsignedInt: value]; } - (instancetype)initWithUnsignedLong: (unsigned long)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, unsignedLongZeroNumberInit); return (id)unsignedLongZeroNumber; #ifdef OF_OBJFW_RUNTIME } else if (value <= (UINTPTR_MAX >> tagBits)) { id ret = objc_createTaggedPointer(numberTag, ((uintptr_t)value << tagBits) | tagUnsignedLong); if (ret != nil) return ret; #endif } return (id)[[OFNumber of_alloc] initWithUnsignedLong: value]; } - (instancetype)initWithUnsignedLongLong: (unsigned long long)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, unsignedLongLongZeroNumberInit); return (id)unsignedLongLongZeroNumber; #ifdef OF_OBJFW_RUNTIME } else if (value <= (UINTPTR_MAX >> tagBits)) { id ret = objc_createTaggedPointer(numberTag, ((uintptr_t)value << tagBits) | tagUnsignedLongLong); if (ret != nil) return ret; #endif } return (id)[[OFNumber of_alloc] initWithUnsignedLongLong: value]; } - (instancetype)initWithFloat: (float)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, floatZeroNumberInit); return (id)floatZeroNumber; } return (id)[[OFNumber of_alloc] initWithFloat: value]; } - (instancetype)initWithDouble: (double)value { if (value == 0) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, doubleZeroNumberInit); return (id)doubleZeroNumber; } return (id)[[OFNumber of_alloc] initWithDouble: value]; } - (instancetype)initWithSerialization: (OFXMLElement *)element |
︙ | ︙ | |||
401 402 403 404 405 406 407 | - (void)release { } - (unsigned int)retainCount { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 | - (void)release { } - (unsigned int)retainCount { return OFMaxRetainCount; } @end #ifdef OF_OBJFW_RUNTIME @implementation OFTaggedPointerNumber - (const char *)objCType { uintptr_t value = object_getTaggedPointerValue(self); switch (value & tagMask) { case tagChar: return @encode(signed char); case tagShort: return @encode(short); case tagInt: return @encode(int); case tagLong: return @encode(long); case tagLongLong: return @encode(long long); case tagUnsignedChar: return @encode(unsigned char); case tagUnsignedShort: return @encode(unsigned short); case tagUnsignedInt: return @encode(unsigned int); case tagUnsignedLong: return @encode(unsigned long); case tagUnsignedLongLong: return @encode(unsigned long long); default: @throw [OFInvalidArgumentException exception]; } } # define RETURN_VALUE \ uintptr_t value = object_getTaggedPointerValue(self); \ \ switch (value & tagMask) { \ case tagChar: \ return (signed char)(unsigned char)(value >> tagBits); \ case tagShort: \ return (short)(unsigned short)(value >> tagBits); \ case tagInt: \ return (int)(unsigned int)(value >> tagBits); \ case tagLong: \ return (long)(unsigned long)(value >> tagBits); \ case tagLongLong: \ return (long long)(unsigned long long)(value >> tagBits); \ case tagUnsignedChar: \ return (unsigned char)(value >> tagBits); \ case tagUnsignedShort: \ return (unsigned short)(value >> tagBits); \ case tagUnsignedInt: \ return (unsigned int)(value >> tagBits); \ case tagUnsignedLong: \ return (unsigned long)(value >> tagBits); \ case tagUnsignedLongLong: \ return (unsigned long long)(value >> tagBits); \ default: \ @throw [OFInvalidArgumentException exception]; \ } - (long long)longLongValue { RETURN_VALUE } - (unsigned long long)unsignedLongLongValue |
︙ | ︙ | |||
508 509 510 511 512 513 514 515 516 517 518 519 520 521 | + (instancetype)alloc { if (self == [OFNumber class]) return (id)&placeholder; return [super alloc]; } + (instancetype)numberWithBool: (bool)value { return [[[self alloc] initWithBool: value] autorelease]; } + (instancetype)numberWithChar: (signed char)value | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 | + (instancetype)alloc { if (self == [OFNumber class]) return (id)&placeholder; return [super alloc]; } + (instancetype)valueWithBytes: (const void *)bytes objCType: (const char *)objCType { OF_UNRECOGNIZED_SELECTOR } + (instancetype)valueWithPointer: (const void *)pointer { OF_UNRECOGNIZED_SELECTOR } + (instancetype)valueWithNonretainedObject: (id)object { OF_UNRECOGNIZED_SELECTOR } + (instancetype)valueWithRange: (OFRange)range { OF_UNRECOGNIZED_SELECTOR } + (instancetype)valueWithPoint: (OFPoint)point { OF_UNRECOGNIZED_SELECTOR } + (instancetype)valueWithSize: (OFSize)size { OF_UNRECOGNIZED_SELECTOR } + (instancetype)valueWithRect: (OFRect)rect { OF_UNRECOGNIZED_SELECTOR } + (instancetype)numberWithBool: (bool)value { return [[[self alloc] initWithBool: value] autorelease]; } + (instancetype)numberWithChar: (signed char)value |
︙ | ︙ | |||
576 577 578 579 580 581 582 583 584 585 586 587 588 589 | + (instancetype)numberWithDouble: (double)value { return [[[self alloc] initWithDouble: value] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithBool: (bool)value { self = [super init]; | > > > > > > | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 | + (instancetype)numberWithDouble: (double)value { return [[[self alloc] initWithDouble: value] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithBytes: (const void *)bytes objCType: (const char *)objCType { OF_INVALID_INIT_METHOD } - (instancetype)initWithBool: (bool)value { self = [super init]; |
︙ | ︙ | |||
748 749 750 751 752 753 754 | self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFString *typeString; if (![element.name isEqual: @"OFNumber"] || | | | | | 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 | self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFString *typeString; if (![element.name isEqual: @"OFNumber"] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; typeString = [element attributeForName: @"type"].stringValue; if ([typeString isEqual: @"bool"]) { OFString *stringValue = element.stringValue; if ([stringValue isEqual: @"true"]) self = [self initWithBool: true]; else if ([stringValue isEqual: @"false"]) self = [self initWithBool: false]; else @throw [OFInvalidArgumentException exception]; } else if ([typeString isEqual: @"float"]) { unsigned long long value = [element unsignedLongLongValueWithBase: 16]; if (value > UINT64_MAX) @throw [OFOutOfRangeException exception]; self = [self initWithDouble: OFFromBigEndianDouble( OFRawUInt64ToDouble(OFToBigEndian64(value)))]; } else if ([typeString isEqual: @"signed"]) self = [self initWithLongLong: element.longLongValue]; else if ([typeString isEqual: @"unsigned"]) self = [self initWithUnsignedLongLong: element.unsignedLongLongValue]; else @throw [OFInvalidArgumentException exception]; |
︙ | ︙ | |||
792 793 794 795 796 797 798 | } - (const char *)objCType { return _typeEncoding; } | | < | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 | } - (const char *)objCType { return _typeEncoding; } - (void)getValue: (void *)value size: (size_t)size { switch (*self.objCType) { #define CASE(enc, type, property) \ case enc: { \ type tmp = (type)self.property; \ \ if (size != sizeof(type)) \ |
︙ | ︙ | |||
941 942 943 944 945 946 947 | if (isSigned(self) || isSigned(number)) return (number.longLongValue == self.longLongValue); return (number.unsignedLongLongValue == self.unsignedLongLongValue); } | < < | | | < < | | | | | | | | | | | | | | | | 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 | if (isSigned(self) || isSigned(number)) return (number.longLongValue == self.longLongValue); return (number.unsignedLongLongValue == self.unsignedLongLongValue); } - (OFComparisonResult)compare: (OFNumber *)number { if (![number isKindOfClass: [OFNumber class]]) @throw [OFInvalidArgumentException exception]; if (isFloat(self) || isFloat(number)) { double double1 = self.doubleValue; double double2 = number.doubleValue; if (double1 > double2) return OFOrderedDescending; if (double1 < double2) return OFOrderedAscending; return OFOrderedSame; } else if (isSigned(self) || isSigned(number)) { long long int1 = self.longLongValue; long long int2 = number.longLongValue; if (int1 > int2) return OFOrderedDescending; if (int1 < int2) return OFOrderedAscending; return OFOrderedSame; } else { unsigned long long uint1 = self.unsignedLongLongValue; unsigned long long uint2 = number.unsignedLongLongValue; if (uint1 > uint2) return OFOrderedDescending; if (uint1 < uint2) return OFOrderedAscending; return OFOrderedSame; } } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); if (isFloat(self)) { double d; if (isnan(self.doubleValue)) return 0; d = OFToLittleEndianDouble(self.doubleValue); for (uint_fast8_t i = 0; i < sizeof(double); i++) OFHashAdd(&hash, ((char *)&d)[i]); } else if (isSigned(self) || isUnsigned(self)) { unsigned long long value = self.unsignedLongLongValue; while (value != 0) { OFHashAdd(&hash, value & 0xFF); value >>= 8; } } else @throw [OFInvalidFormatException exception]; OFHashFinalize(&hash); return hash; } - (id)copy { return [self retain]; |
︙ | ︙ | |||
1045 1046 1047 1048 1049 1050 1051 | - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: @"OFNumber" | | | < | < < > | < | < | > | < | > | | < | < | | < < | < | | < < | < | < | < < | | < < | < | | < < | < | | < < | < < | < | < < | | < < | < | | < < | < | | < < | < | 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 | - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: @"OFNumber" namespace: OFSerializationNS stringValue: self.description]; if (*self.objCType == 'B') [element addAttributeWithName: @"type" stringValue: @"bool"]; else if (isFloat(self)) { [element addAttributeWithName: @"type" stringValue: @"float"]; element.stringValue = [OFString stringWithFormat: @"%016" PRIx64, OFFromBigEndian64(OFDoubleToRawUInt64(OFToBigEndianDouble( self.doubleValue)))]; } else if (isSigned(self)) [element addAttributeWithName: @"type" stringValue: @"signed"]; else if (isUnsigned(self)) [element addAttributeWithName: @"type" stringValue: @"unsigned"]; else @throw [OFInvalidFormatException exception]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } - (OFString *)JSONRepresentation { return [self of_JSONRepresentationWithOptions: 0 depth: 0]; } - (OFString *)JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options { return [self of_JSONRepresentationWithOptions: options depth: 0]; } - (OFString *) of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options depth: (size_t)depth { double doubleValue; if (*self.objCType == 'B') return (self.boolValue ? @"true" : @"false"); doubleValue = self.doubleValue; if (isinf(doubleValue)) { if (options & OFJSONRepresentationOptionJSON5) { if (doubleValue > 0) return @"Infinity"; else return @"-Infinity"; } else @throw [OFInvalidArgumentException exception]; } return self.description; } - (OFData *)messagePackRepresentation { OFMutableData *data; const char *typeEncoding = self.objCType; if (*typeEncoding == 'B') { uint8_t type = (self.boolValue ? 0xC3 : 0xC2); data = [OFMutableData dataWithItems: &type count: 1]; } else if (*typeEncoding == 'f') { uint8_t type = 0xCA; float tmp = OFToBigEndianFloat(self.floatValue); data = [OFMutableData dataWithCapacity: 5]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (*typeEncoding == 'd') { uint8_t type = 0xCB; double tmp = OFToBigEndianDouble(self.doubleValue); data = [OFMutableData dataWithCapacity: 9]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (isSigned(self)) { long long value = self.longLongValue; if (value >= -32 && value < 0) { uint8_t tmp = 0xE0 | ((uint8_t)(value - 32) & 0x1F); data = [OFMutableData dataWithItems: &tmp count: 1]; } else if (value >= INT8_MIN && value <= INT8_MAX) { uint8_t type = 0xD0; int8_t tmp = (int8_t)value; data = [OFMutableData dataWithCapacity: 2]; [data addItem: &type]; [data addItem: &tmp]; } else if (value >= INT16_MIN && value <= INT16_MAX) { uint8_t type = 0xD1; int16_t tmp = OFToBigEndian16((int16_t)value); data = [OFMutableData dataWithCapacity: 3]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (value >= INT32_MIN && value <= INT32_MAX) { uint8_t type = 0xD2; int32_t tmp = OFToBigEndian32((int32_t)value); data = [OFMutableData dataWithCapacity: 5]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (value >= INT64_MIN && value <= INT64_MAX) { uint8_t type = 0xD3; int64_t tmp = OFToBigEndian64((int64_t)value); data = [OFMutableData dataWithCapacity: 9]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; } else if (isUnsigned(self)) { unsigned long long value = self.unsignedLongLongValue; if (value <= 127) { uint8_t tmp = ((uint8_t)value & 0x7F); data = [OFMutableData dataWithItems: &tmp count: 1]; } else if (value <= UINT8_MAX) { uint8_t type = 0xCC; uint8_t tmp = (uint8_t)value; data = [OFMutableData dataWithCapacity: 2]; [data addItem: &type]; [data addItem: &tmp]; } else if (value <= UINT16_MAX) { uint8_t type = 0xCD; uint16_t tmp = OFToBigEndian16((uint16_t)value); data = [OFMutableData dataWithCapacity: 3]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (value <= UINT32_MAX) { uint8_t type = 0xCE; uint32_t tmp = OFToBigEndian32((uint32_t)value); data = [OFMutableData dataWithCapacity: 5]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (value <= UINT64_MAX) { uint8_t type = 0xCF; uint64_t tmp = OFToBigEndian64((uint64_t)value); data = [OFMutableData dataWithCapacity: 9]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; } else @throw [OFInvalidFormatException exception]; [data makeImmutable]; return data; } @end |
Modified src/OFObject+KeyValueCoding.h from [9dc6563122] to [c0e7932d00].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFObject+KeyValueCoding.m from [907d6adb03] to [8a83d2aa9e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
46 47 48 49 50 51 52 | char *name; if ((keyLength = key.UTF8StringLength) < 1) { objc_autoreleasePoolPop(pool); return [self valueForUndefinedKey: key]; } | | | | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | char *name; if ((keyLength = key.UTF8StringLength) < 1) { objc_autoreleasePoolPop(pool); return [self valueForUndefinedKey: key]; } name = OFAllocMemory(keyLength + 3, 1); @try { memcpy(name, "is", 2); memcpy(name + 2, key.UTF8String, keyLength); name[keyLength + 2] = '\0'; name[2] = OFASCIIToUpper(name[2]); selector = sel_registerName(name); } @finally { OFFreeMemory(name); } methodSignature = [self methodSignatureForSelector: selector]; if (methodSignature == NULL) { objc_autoreleasePoolPop(pool); return [self valueForUndefinedKey: key]; |
︙ | ︙ | |||
137 138 139 140 141 142 143 | objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (id)valueForUndefinedKey: (OFString *)key { | | < | < < | | | | < | | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (id)valueForUndefinedKey: (OFString *)key { @throw [OFUndefinedKeyException exceptionWithObject: self key: key]; } - (void)setValue: (id)value forKey: (OFString *)key { void *pool = objc_autoreleasePoolPush(); size_t keyLength; char *name; SEL selector; OFMethodSignature *methodSignature; const char *valueType; if ((keyLength = key.UTF8StringLength) < 1) { objc_autoreleasePoolPop(pool); [self setValue: value forUndefinedKey: key]; return; } name = OFAllocMemory(keyLength + 5, 1); @try { memcpy(name, "set", 3); memcpy(name + 3, key.UTF8String, keyLength); memcpy(name + keyLength + 3, ":", 2); name[3] = OFASCIIToUpper(name[3]); selector = sel_registerName(name); } @finally { OFFreeMemory(name); } methodSignature = [self methodSignatureForSelector: selector]; if (methodSignature == nil || methodSignature.numberOfArguments != 3 || *methodSignature.methodReturnType != 'v' || *[methodSignature argumentTypeAtIndex: 0] != '@' || *[methodSignature argumentTypeAtIndex: 1] != ':') { objc_autoreleasePoolPop(pool); [self setValue: value forUndefinedKey: key]; return; } valueType = [methodSignature argumentTypeAtIndex: 2]; if (*valueType != '@' && *valueType != '#' && value == nil) { objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
226 227 228 229 230 231 232 | CASE('L', unsigned long, unsignedLongValue) CASE('Q', unsigned long long, unsignedLongLongValue) CASE('f', float, floatValue) CASE('d', double, doubleValue) #undef CASE default: objc_autoreleasePoolPop(pool); | < | | < | < | < | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | CASE('L', unsigned long, unsignedLongValue) CASE('Q', unsigned long long, unsignedLongLongValue) CASE('f', float, floatValue) CASE('d', double, doubleValue) #undef CASE default: objc_autoreleasePoolPop(pool); [self setValue: value forUndefinedKey: key]; return; } objc_autoreleasePoolPop(pool); } - (void)setValue: (id)value forKeyPath: (OFString *)keyPath { void *pool = objc_autoreleasePoolPush(); OFArray *keys = [keyPath componentsSeparatedByString: @"."]; size_t keysCount = keys.count; id object = self; size_t i = 0; for (OFString *key in keys) { if (++i == keysCount) [object setValue: value forKey: key]; else object = [object valueForKey: key]; } objc_autoreleasePoolPop(pool); } - (void)setValue: (id)value forUndefinedKey: (OFString *)key { @throw [OFUndefinedKeyException exceptionWithObject: self key: key value: value]; } - (void)setNilValueForKey: (OFString *)key { @throw [OFInvalidArgumentException exception]; } @end |
Modified src/OFObject+Serialization.h from [d3572770d9] to [ed19e260ae].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFObject+Serialization.m from [bd3824da74] to [0bfdaef011].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
40 41 42 43 44 45 46 | abort(); } pool = objc_autoreleasePoolPush(); element = ((id <OFSerialization>)self).XMLElementBySerializing; root = [OFXMLElement elementWithName: @"serialization" | | | < | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | abort(); } pool = objc_autoreleasePoolPush(); element = ((id <OFSerialization>)self).XMLElementBySerializing; root = [OFXMLElement elementWithName: @"serialization" namespace: OFSerializationNS]; [root addAttributeWithName: @"version" stringValue: @"1"]; [root addChild: element]; ret = [@"<?xml version='1.0' encoding='UTF-8'?>\n" stringByAppendingString: [root XMLStringWithIndentation: 2]]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } @end |
Modified src/OFObject.h from [6ddaa1e48b] to [48eed47979].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | #endif #include <stddef.h> #include <stdint.h> #include <stdbool.h> #include <limits.h> | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #endif #include <stddef.h> #include <stdint.h> #include <stdbool.h> #include <limits.h> #include "macros.h" #include "OFOnce.h" /* * Some versions of MinGW require <winsock2.h> to be included before * <windows.h>. Do this here to make sure this is always done in the correct * order, even if another header includes just <windows.h>. */ #ifdef __MINGW32__ |
︙ | ︙ | |||
54 55 56 57 58 59 60 | /** @file */ /** * @brief A result of a comparison. */ typedef enum { /** The left object is smaller than the right */ | | | | | < | | | > > | > > > > | | | < | | | | | | | | | | < | | | | | | | | | | | | | < | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | > | | < | < > | | > > > | > | > | < < | | < | < > | | | < | < | | < < | < > > | < > > > < < > | < | > | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | /** @file */ /** * @brief A result of a comparison. */ typedef enum { /** The left object is smaller than the right */ OFOrderedAscending = -1, /** Both objects are equal */ OFOrderedSame = 0, /** The left object is bigger than the right */ OFOrderedDescending = 1 } OFComparisonResult; #ifdef OF_HAVE_BLOCKS /** * @brief A comparator to compare two objects. * * @param left The left object * @param right The right object * @return The order of the objects */ typedef OFComparisonResult (^OFComparator)(id _Nonnull left, id _Nonnull right); #endif /** * @brief An enum for representing endianess. */ typedef enum { /** Most significant byte first (big endian) */ OFByteOrderBigEndian, /** Least significant byte first (little endian) */ OFByteOrderLittleEndian, /** Native byte order of the system */ #ifdef OF_BIG_ENDIAN OFByteOrderNative = OFByteOrderBigEndian #else OFByteOrderNative = OFByteOrderLittleEndian #endif } OFByteOrder; /** * @struct OFRange OFObject.h ObjFW/OFObject.h * * @brief A range. */ typedef struct OF_BOXABLE { /** The start of the range */ size_t location; /** The length of the range */ size_t length; } OFRange; /** * @brief Creates a new OFRange. * * @param start The starting index of the range * @param length The length of the range * @return An OFRangeith the specified start and length */ static OF_INLINE OFRange OF_CONST_FUNC OFRangeMake(size_t start, size_t length) { OFRange range = { start, length }; return range; } /** * @brief Returns whether the two ranges are equal. * * @param range1 The first range for the comparison * @param range2 The second range for the comparison * @return Whether the two ranges are equal */ static OF_INLINE bool OFRangeEqual(OFRange range1, OFRange range2) { if (range1.location != range2.location) return false; if (range1.length != range2.length) return false; return true; } /** * @brief A time interval in seconds. */ typedef double OFTimeInterval; /** * @struct OFPoint OFObject.h ObjFW/OFObject.h * * @brief A point. */ typedef struct OF_BOXABLE { /** The x coordinate of the point */ float x; /** The y coordinate of the point */ float y; } OFPoint; /** * @brief Creates a new OFPoint. * * @param x The x coordinate of the point * @param y The x coordinate of the point * @return An OFPoint with the specified coordinates */ static OF_INLINE OFPoint OF_CONST_FUNC OFPointMake(float x, float y) { OFPoint point = { x, y }; return point; } /** * @brief Returns whether the two points are equal. * * @param point1 The first point for the comparison * @param point2 The second point for the comparison * @return Whether the two points are equal */ static OF_INLINE bool OFPointEqual(OFPoint point1, OFPoint point2) { if (point1.x != point2.x) return false; if (point1.y != point2.y) return false; return true; } /** * @struct OFSize OFObject.h ObjFW/OFObject.h * * @brief A size. */ typedef struct OF_BOXABLE { /** The width of the size */ float width; /** The height of the size */ float height; } OFSize; /** * @brief Creates a new OFSize. * * @param width The width of the size * @param height The height of the size * @return An OFSize with the specified width and height */ static OF_INLINE OFSize OF_CONST_FUNC OFSizeMake(float width, float height) { OFSize size = { width, height }; return size; } /** * @brief Returns whether the two sizes are equal. * * @param size1 The first size for the comparison * @param size2 The second size for the comparison * @return Whether the two sizes are equal */ static OF_INLINE bool OFSizeEqual(OFSize size1, OFSize size2) { if (size1.width != size2.width) return false; if (size1.height != size2.height) return false; return true; } /** * @struct OFRect OFObject.h ObjFW/OFObject.h * * @brief A rectangle. */ typedef struct OF_BOXABLE { /** The point from where the rectangle originates */ OFPoint origin; /** The size of the rectangle */ OFSize size; } OFRect; /** * @brief Creates a new OFRect. * * @param x The x coordinate of the top left corner of the rectangle * @param y The y coordinate of the top left corner of the rectangle * @param width The width of the rectangle * @param height The height of the rectangle * @return An OFRect with the specified origin and size */ static OF_INLINE OFRect OF_CONST_FUNC OFRectMake(float x, float y, float width, float height) { OFRect rect = { OFPointMake(x, y), OFSizeMake(width, height) }; return rect; } /** * @brief Returns whether the two rectangles are equal. * * @param rect1 The first rectangle for the comparison * @param rect2 The second rectangle for the comparison * @return Whether the two rectangles are equal */ static OF_INLINE bool OFRectEqual(OFRect rect1, OFRect rect2) { if (!OFPointEqual(rect1.origin, rect2.origin)) return false; if (!OFSizeEqual(rect1.size, rect2.size)) return false; return true; } /** * @brief Adds the specified byte to the hash. * * @param hash A pointer to a hash to add the byte to * @param byte The byte to add to the hash */ static OF_INLINE void OFHashAdd(unsigned long *_Nonnull hash, unsigned char byte) { uint32_t tmp = (uint32_t)*hash; tmp += byte; tmp += tmp << 10; tmp ^= tmp >> 6; *hash = tmp; } /** * @brief Adds the specified hash to the hash. * * @param hash A pointer to a hash to add the hash to * @param otherHash The hash to add to the hash */ static OF_INLINE void OFHashAddHash(unsigned long *_Nonnull hash, unsigned long otherHash) { OFHashAdd(hash, (otherHash >> 24) & 0xFF); OFHashAdd(hash, (otherHash >> 16) & 0xFF); OFHashAdd(hash, (otherHash >> 8) & 0xFF); OFHashAdd(hash, otherHash & 0xFF); } /** * @brief Finalizes the specified hash. * * @param hash A pointer to the hash to finalize */ static OF_INLINE void OFHashFinalize(unsigned long *_Nonnull hash) { uint32_t tmp = (uint32_t)*hash; tmp += tmp << 3; tmp ^= tmp >> 11; tmp += tmp << 15; *hash = tmp; } static const size_t OFNotFound = SIZE_MAX; #ifdef __OBJC__ @class OFMethodSignature; @class OFString; @class OFThread; /** |
︙ | ︙ | |||
399 400 401 402 403 404 405 | * @brief Performs the specified selector with the specified object. * * @param selector The selector to perform * @param object The object that is passed to the method specified by the * selector * @return The object returned by the method specified by the selector */ | | < | 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 | * @brief Performs the specified selector with the specified object. * * @param selector The selector to perform * @param object The object that is passed to the method specified by the * selector * @return The object returned by the method specified by the selector */ - (nullable id)performSelector: (SEL)selector withObject: (nullable id)object; /** * @brief Performs the specified selector with the specified objects. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the * selector |
︙ | ︙ | |||
535 536 537 538 539 540 541 | @property (class, readonly, nonatomic, getter=class) Class class_; # endif @property (class, readonly, nonatomic) OFString *className; @property (class, readonly, nullable, nonatomic) Class superclass; @property (class, readonly, nonatomic) OFString *description; # endif | | | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | @property (class, readonly, nonatomic, getter=class) Class class_; # endif @property (class, readonly, nonatomic) OFString *className; @property (class, readonly, nullable, nonatomic) Class superclass; @property (class, readonly, nonatomic) OFString *description; # endif # ifndef __cplusplus @property (readonly, nonatomic) Class class; # else @property (readonly, nonatomic, getter=class) Class class_; #endif @property OF_NULLABLE_PROPERTY (readonly, nonatomic) Class superclass; @property (readonly, nonatomic) unsigned long hash; @property (readonly, nonatomic) unsigned int retainCount; |
︙ | ︙ | |||
575 576 577 578 579 580 581 | /** * @brief A method which is called when the class is unloaded from the runtime. * * Derived classes can override this to execute their own code when the class * is unloaded. * * @warning This is not supported by the Apple runtime and currently only | | < | | 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 | /** * @brief A method which is called when the class is unloaded from the runtime. * * Derived classes can override this to execute their own code when the class * is unloaded. * * @warning This is not supported by the Apple runtime and currently only * called by the ObjFW runtime when @ref objc_deinit has been called! * In the future, this might also be called by the ObjFW runtime when * the class is part of a plugin that is being unloaded. */ + (void)unload; /** * @brief A method which is called the moment before the first call to the class * is being made. * |
︙ | ︙ | |||
802 803 804 805 806 807 808 | * * @param selector The selector for which the method signature should be * returned * @return The method signature for the specified selector */ - (nullable OFMethodSignature *)methodSignatureForSelector: (SEL)selector; | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | | | | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 | * * @param selector The selector for which the method signature should be * returned * @return The method signature for the specified selector */ - (nullable OFMethodSignature *)methodSignatureForSelector: (SEL)selector; /** * @brief Deallocates the object. * * It is automatically called when the retain count reaches zero. * * This also frees all memory in its memory pool. */ - (void)dealloc; /** * @brief Performs the specified selector after the specified delay. * * @param selector The selector to perform * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector afterDelay: (OFTimeInterval)delay; /** * @brief Performs the specified selector with the specified object after the * specified delay. * * @param selector The selector to perform * @param object The object that is passed to the method specified by the * selector * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector withObject: (nullable id)object afterDelay: (OFTimeInterval)delay; /** * @brief Performs the specified selector with the specified objects after the * specified delay. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the * selector * @param object2 The second object that is passed to the method specified by * the selector * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector withObject: (nullable id)object1 withObject: (nullable id)object2 afterDelay: (OFTimeInterval)delay; /** * @brief Performs the specified selector with the specified objects after the * specified delay. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the * selector * @param object2 The second object that is passed to the method specified by * the selector * @param object3 The third object that is passed to the method specified by the * selector * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 afterDelay: (OFTimeInterval)delay; /** * @brief Performs the specified selector with the specified objects after the * specified delay. * * @param selector The selector to perform * @param object1 The first object that is passed to the method specified by the |
︙ | ︙ | |||
979 980 981 982 983 984 985 | * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 withObject: (nullable id)object4 | | | 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 | * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 withObject: (nullable id)object4 afterDelay: (OFTimeInterval)delay; # ifdef OF_HAVE_THREADS /** * @brief Performs the specified selector on the specified thread. * * @param selector The selector to perform * @param thread The thread on which to perform the selector |
︙ | ︙ | |||
1160 1161 1162 1163 1164 1165 1166 | * * @param selector The selector to perform * @param thread The thread on which to perform the selector * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector onThread: (OFThread *)thread | | | | | | 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 | * * @param selector The selector to perform * @param thread The thread on which to perform the selector * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector onThread: (OFThread *)thread afterDelay: (OFTimeInterval)delay; /** * @brief Performs the specified selector on the specified thread with the * specified object after the specified delay. * * @param selector The selector to perform * @param thread The thread on which to perform the selector * @param object The object that is passed to the method specified by the * selector * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (nullable id)object afterDelay: (OFTimeInterval)delay; /** * @brief Performs the specified selector on the specified thread with the * specified objects after the specified delay. * * @param selector The selector to perform * @param thread The thread on which to perform the selector * @param object1 The first object that is passed to the method specified by the * selector * @param object2 The second object that is passed to the method specified by * the selector * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (nullable id)object1 withObject: (nullable id)object2 afterDelay: (OFTimeInterval)delay; /** * @brief Performs the specified selector on the specified thread with the * specified objects after the specified delay. * * @param selector The selector to perform * @param thread The thread on which to perform the selector * @param object1 The first object that is passed to the method specified by the * selector * @param object2 The second object that is passed to the method specified by * the selector * @param object3 The third object that is passed to the method specified by the * selector * @param delay The delay after which the selector will be performed */ - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 afterDelay: (OFTimeInterval)delay; /** * @brief Performs the specified selector on the specified thread with the * specified objects after the specified delay. * * @param selector The selector to perform * @param thread The thread on which to perform the selector |
︙ | ︙ | |||
1238 1239 1240 1241 1242 1243 1244 | */ - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 withObject: (nullable id)object4 | | | 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 | */ - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (nullable id)object1 withObject: (nullable id)object2 withObject: (nullable id)object3 withObject: (nullable id)object4 afterDelay: (OFTimeInterval)delay; # endif /** * @brief This method is called when @ref resolveClassMethod: or * @ref resolveInstanceMethod: returned false. It should return a target * to which the message should be forwarded. * |
︙ | ︙ | |||
1309 1310 1311 1312 1313 1314 1315 | @end /** * @protocol OFComparing OFObject.h ObjFW/OFObject.h * * @brief A protocol for comparing objects. * | | | | | > > > | | | > > | | > > | | | < | > | | | | | > > > | > | > > > > > > | > > > > > > | > > > > > > > > > | 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 | @end /** * @protocol OFComparing OFObject.h ObjFW/OFObject.h * * @brief A protocol for comparing objects. * * This protocol is implemented by objects that can be compared. Its only method, @ref compare:, should be overridden with a stronger type. */ @protocol OFComparing /** * @brief Compares the object to another object. * * @param object An object to compare the object to * @return The result of the comparison */ - (OFComparisonResult)compare: (id <OFComparing>)object; @end #endif #ifdef __cplusplus extern "C" { #endif /** * @brief Allocates memory for the specified number of items of the specified * size. * * To free the allocated memory, use @ref OFFreeMemory. * * Throws @ref OFOutOfMemoryException if allocating failed and * @ref OFOutOfRangeException if the requested size exceeds the address space. * * @param count The number of items to allocate * @param size The size of each item to allocate * @return A pointer to the allocated memory. May return NULL if the specified * size or count is 0. */ extern void *_Nullable OFAllocMemory(size_t count, size_t size) OF_WARN_UNUSED_RESULT; /** * @brief Allocates memory for the specified number of items of the specified * size and initializes it with zeros. * * To free the allocated memory, use @ref OFFreeMemory. * * Throws @ref OFOutOfMemoryException if allocating failed and * @ref OFOutOfRangeException if the requested size exceeds the address space. * * @param size The size of each item to allocate * @param count The number of items to allocate * @return A pointer to the allocated memory. May return NULL if the specified * size or count is 0. */ extern void *_Nullable OFAllocZeroedMemory(size_t count, size_t size) OF_WARN_UNUSED_RESULT; /** * @brief Resizes memory to the specified number of items of the specified size. * * To free the allocated memory, use @ref OFFreeMemory. * * If the pointer is NULL, this is equivalent to allocating memory. * If the size or number of items is 0, this is equivalent to freeing memory. * * Throws @ref OFOutOfMemoryException if allocating failed and * @ref OFOutOfRangeException if the requested size exceeds the address space. * * @param pointer A pointer to the already allocated memory * @param size The size of each item to resize to * @param count The number of items to resize to * @return A pointer to the resized memory chunk */ extern void *_Nullable OFResizeMemory(void *_Nullable pointer, size_t count, size_t size) OF_WARN_UNUSED_RESULT; /** * @brief Frees memory allocated by @ref OFAllocMemory, @ref OFAllocZeroedMemory * or @ref OFResizeMemory. * * @param pointer A pointer to the memory to free or nil (passing nil ooes * nothing) */ extern void OFFreeMemory(void *_Nullable pointer); #ifdef OF_APPLE_RUNTIME extern void *_Null_unspecified objc_autoreleasePoolPush(void); extern void objc_autoreleasePoolPop(void *_Null_unspecified pool); # ifndef __OBJC2__ extern id _Nullable objc_constructInstance(Class _Nullable class_, void *_Nullable bytes); extern void *_Nullable objc_destructInstance(id _Nullable object); # endif #endif extern id OFAllocObject(Class class_, size_t extraSize, size_t extraAlignment, void *_Nullable *_Nullable extra); extern void OF_NO_RETURN_FUNC OFMethodNotFound(id self, SEL _cmd); /** * @brief Returns 16 bit or non-cryptographical randomness. * * @return 16 bit or non-cryptographical randomness */ extern uint16_t OFRandom16(void); /** * @brief Returns 32 bit or non-cryptographical randomness. * * @return 32 bit or non-cryptographical randomness */ extern uint32_t OFRandom32(void); /** * @brief Returns 64 bit or non-cryptographical randomness. * * @return 64 bit or non-cryptographical randomness */ extern uint64_t OFRandom64(void); /** * @brief Initializes the specified hash. * * @param hash A pointer to the hash to initialize */ extern void OFHashInit(unsigned long *_Nonnull hash); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END #include "OFBlock.h" #ifdef __OBJC__ # import "OFObject+KeyValueCoding.h" # import "OFObject+Serialization.h" #endif #endif |
Modified src/OFObject.m from [133c2d9091] to [fe35d606d6].
1 | /* | < < | > > > > > > > > < < < < < < < < < | | | | | | < < < < < < | | < < < < | | | | | > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "unistd_wrapper.h" #include <assert.h> #ifdef OF_APPLE_RUNTIME # include <dlfcn.h> #endif #ifdef HAVE_GETRANDOM # include <sys/random.h> #endif #import "OFObject.h" #import "OFArray.h" #ifdef OF_HAVE_ATOMIC_OPS # import "OFAtomic.h" #endif #import "OFLocale.h" #import "OFMethodSignature.h" #import "OFRunLoop.h" #if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS) # import "OFPlainMutex.h" /* For OFSpinlock */ #endif #import "OFString.h" #import "OFThread.h" #import "OFTimer.h" #import "OFAllocFailedException.h" #import "OFEnumerationMutationException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFNotImplementedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #if defined(OF_APPLE_RUNTIME) && __OBJC2__ # import <objc/objc-exception.h> #elif defined(OF_OBJFW_RUNTIME) # import "ObjFWRT.h" #endif #ifdef OF_WINDOWS # include <windows.h> #endif #ifdef OF_AMIGAOS # include <proto/exec.h> #endif #ifdef OF_APPLE_RUNTIME extern id _Nullable _objc_rootAutorelease(id _Nullable object); #endif #if defined(OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR) extern id OFForward(id, SEL, ...); extern struct Stret OFForward_stret(id, SEL, ...); #else # define OFForward OFMethodNotFound # define OFForward_stret OFMethodNotFound_stret #endif struct PreIvars { int retainCount; #if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS) OFSpinlock retainCountSpinlock; #endif }; #define PRE_IVARS_ALIGN ((sizeof(struct PreIvars) + \ (OF_BIGGEST_ALIGNMENT - 1)) & ~(OF_BIGGEST_ALIGNMENT - 1)) #define PRE_IVARS ((struct PreIvars *)(void *)((char *)self - PRE_IVARS_ALIGN)) static struct { Class isa; } allocFailedException; unsigned long OFHashSeed; void * OFAllocMemory(size_t count, size_t size) { void *pointer; if OF_UNLIKELY (count == 0 || size == 0) return NULL; if OF_UNLIKELY (count > SIZE_MAX / size) @throw [OFOutOfRangeException exception]; if OF_UNLIKELY ((pointer = malloc(count * size)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: size]; return pointer; } void * OFAllocZeroedMemory(size_t count, size_t size) { void *pointer; if OF_UNLIKELY (count == 0 || size == 0) return NULL; /* Not all calloc implementations check for overflow. */ if OF_UNLIKELY (count > SIZE_MAX / size) @throw [OFOutOfRangeException exception]; if OF_UNLIKELY ((pointer = calloc(count, size)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: size]; return pointer; } void * OFResizeMemory(void *pointer, size_t count, size_t size) { if OF_UNLIKELY (count == 0 || size == 0) { free(pointer); return NULL; } if OF_UNLIKELY (count > SIZE_MAX / size) @throw [OFOutOfRangeException exception]; if OF_UNLIKELY ((pointer = realloc(pointer, count * size)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: size]; return pointer; } void OFFreeMemory(void *pointer) { free(pointer); } #if !defined(HAVE_ARC4RANDOM) && !defined(HAVE_GETRANDOM) static void initRandom(void) |
︙ | ︙ | |||
180 181 182 183 184 185 186 | gettimeofday(&tv, NULL); srand((unsigned)(tv.tv_sec ^ tv.tv_usec)); # endif } #endif uint16_t | | | < | | | | | | | | > > > > > > | | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | gettimeofday(&tv, NULL); srand((unsigned)(tv.tv_sec ^ tv.tv_usec)); # endif } #endif uint16_t OFRandom16(void) { #if defined(HAVE_ARC4RANDOM) return arc4random(); #elif defined(HAVE_GETRANDOM) uint16_t buffer; OFEnsure(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); return buffer; #else static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, initRandom); # ifdef HAVE_RANDOM return random() & 0xFFFF; # else return rand() & 0xFFFF; # endif #endif } uint32_t OFRandom32(void) { #if defined(HAVE_ARC4RANDOM) return arc4random(); #elif defined(HAVE_GETRANDOM) uint32_t buffer; OFEnsure(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); return buffer; #else return ((uint32_t)OFRandom16() << 16) | OFRandom16(); #endif } uint64_t OFRandom64(void) { #if defined(HAVE_ARC4RANDOM_BUF) uint64_t buffer; arc4random_buf(&buffer, sizeof(buffer)); return buffer; #elif defined(HAVE_GETRANDOM) uint64_t buffer; OFEnsure(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); return buffer; #else return ((uint64_t)OFRandom32() << 32) | OFRandom32(); #endif } void OFHashInit(unsigned long *hash) { *hash = OFHashSeed; } static const char * typeEncodingForSelector(Class class, SEL selector) { Method method; if ((method = class_getInstanceMethod(class, selector)) == NULL) return NULL; return method_getTypeEncoding(method); } #if !defined(OF_APPLE_RUNTIME) || defined(__OBJC2__) static void uncaughtExceptionHandler(id exception) { OFString *description = [exception description]; OFArray *backtrace = nil; OFStringEncoding encoding = [OFLocale encoding]; fprintf(stderr, "\nRuntime error: Unhandled exception:\n%s\n", [description cStringWithEncoding: encoding]); if ([exception respondsToSelector: @selector(backtrace)]) backtrace = [exception backtrace]; |
︙ | ︙ | |||
280 281 282 283 284 285 286 | static void enumerationMutationHandler(id object) { @throw [OFEnumerationMutationException exceptionWithObject: object]; } void OF_NO_RETURN_FUNC | | | | | | | | | 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | static void enumerationMutationHandler(id object) { @throw [OFEnumerationMutationException exceptionWithObject: object]; } void OF_NO_RETURN_FUNC OFMethodNotFound(id object, SEL selector) { [object doesNotRecognizeSelector: selector]; /* * Just in case doesNotRecognizeSelector: returned, even though it must * never return. */ abort(); OF_UNREACHABLE } void OF_NO_RETURN_FUNC OFMethodNotFound_stret(void *stret, id object, SEL selector) { OFMethodNotFound(object, selector); } id OFAllocObject(Class class, size_t extraSize, size_t extraAlignment, void **extra) { OFObject *instance; size_t instanceSize; instanceSize = class_getInstanceSize(class); if OF_UNLIKELY (extraAlignment > 1) extraAlignment = ((instanceSize + extraAlignment - 1) & ~(extraAlignment - 1)) - extraAlignment; instance = calloc(1, PRE_IVARS_ALIGN + instanceSize + extraAlignment + extraSize); if OF_UNLIKELY (instance == nil) { allocFailedException.isa = [OFAllocFailedException class]; @throw (id)&allocFailedException; } ((struct PreIvars *)instance)->retainCount = 1; #if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS) if OF_UNLIKELY (OFSpinlockNew( &((struct PreIvars *)instance)->retainCountSpinlock) != 0) { free(instance); @throw [OFInitializationFailedException exceptionWithClass: class]; } #endif instance = (OFObject *)(void *)((char *)instance + PRE_IVARS_ALIGN); |
︙ | ︙ | |||
377 378 379 380 381 382 383 | * handler on load, we should not set ours, as this will break * Foundation. * * Unfortunately, there is no way to check if a forward handler has * already been set, so this is the best we can do. */ if (dlsym(RTLD_DEFAULT, "NSFoundationVersionNumber") == NULL) | | | | | | | | | | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | * handler on load, we should not set ours, as this will break * Foundation. * * Unfortunately, there is no way to check if a forward handler has * already been set, so this is the best we can do. */ if (dlsym(RTLD_DEFAULT, "NSFoundationVersionNumber") == NULL) objc_setForwardHandler((void *)&OFForward, (void *)&OFForward_stret); #else objc_setForwardHandler((IMP)&OFForward, (IMP)&OFForward_stret); #endif objc_setEnumerationMutationHandler(enumerationMutationHandler); do { OFHashSeed = OFRandom32(); } while (OFHashSeed == 0); #ifdef OF_OBJFW_RUNTIME objc_setTaggedPointerSecret(sizeof(uintptr_t) == 4 ? (uintptr_t)OFRandom32() : (uintptr_t)OFRandom64()); #endif } + (void)unload { } + (void)initialize { } + (instancetype)alloc { return OFAllocObject(self, 0, 0, NULL); } + (instancetype)new { return [[self alloc] init]; } + (Class)class { return self; } + (OFString *)className { return [OFString stringWithCString: class_getName(self) encoding: OFStringEncodingASCII]; } + (bool)isSubclassOfClass: (Class)class { for (Class iter = self; iter != Nil; iter = class_getSuperclass(iter)) if (iter == class) return true; |
︙ | ︙ | |||
474 475 476 477 478 479 480 | } + (OFString *)description { return [self className]; } | | < | < | 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 | } + (OFString *)description { return [self className]; } + (IMP)replaceClassMethod: (SEL)selector withMethodFromClass: (Class)class { IMP method = [class methodForSelector: selector]; if (method == NULL) @throw [OFInvalidArgumentException exception]; return class_replaceMethod(object_getClass(self), selector, method, typeEncodingForSelector(object_getClass(class), selector)); } + (IMP)replaceInstanceMethod: (SEL)selector withMethodFromClass: (Class)class { IMP method = [class instanceMethodForSelector: selector]; if (method == NULL) @throw [OFInvalidArgumentException exception]; return class_replaceMethod(self, selector, method, |
︙ | ︙ | |||
578 579 580 581 582 583 584 | { return class_getSuperclass(object_getClass(self)); } - (OFString *)className { return [OFString stringWithCString: object_getClassName(self) | | | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | { return class_getSuperclass(object_getClass(self)); } - (OFString *)className { return [OFString stringWithCString: object_getClassName(self) encoding: OFStringEncodingASCII]; } - (bool)isKindOfClass: (Class)class { for (Class iter = object_getClass(self); iter != Nil; iter = class_getSuperclass(iter)) if (iter == class) |
︙ | ︙ | |||
622 623 624 625 626 627 628 | #elif defined(OF_APPLE_RUNTIME) id (*imp)(id, SEL) = (id (*)(id, SEL))objc_msgSend; #endif return imp(self, selector); } | | < | 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 | #elif defined(OF_APPLE_RUNTIME) id (*imp)(id, SEL) = (id (*)(id, SEL))objc_msgSend; #endif return imp(self, selector); } - (id)performSelector: (SEL)selector withObject: (id)object { #if defined(OF_OBJFW_RUNTIME) id (*imp)(id, SEL, id) = (id (*)(id, SEL, id))objc_msg_lookup(self, selector); #elif defined(OF_APPLE_RUNTIME) id (*imp)(id, SEL, id) = (id (*)(id, SEL, id))objc_msgSend; #endif |
︙ | ︙ | |||
682 683 684 685 686 687 688 | id (*imp)(id, SEL, id, id, id, id) = (id (*)(id, SEL, id, id, id, id))objc_msgSend; #endif return imp(self, selector, object1, object2, object3, object4); } | | < | | | | | 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 | id (*imp)(id, SEL, id, id, id, id) = (id (*)(id, SEL, id, id, id, id))objc_msgSend; #endif return imp(self, selector, object1, object2, object3, object4); } - (void)performSelector: (SEL)selector afterDelay: (OFTimeInterval)delay { void *pool = objc_autoreleasePoolPush(); [OFTimer scheduledTimerWithTimeInterval: delay target: self selector: selector repeats: false]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector withObject: (id)object afterDelay: (OFTimeInterval)delay { void *pool = objc_autoreleasePoolPush(); [OFTimer scheduledTimerWithTimeInterval: delay target: self selector: selector object: object repeats: false]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector withObject: (id)object1 withObject: (id)object2 afterDelay: (OFTimeInterval)delay { void *pool = objc_autoreleasePoolPush(); [OFTimer scheduledTimerWithTimeInterval: delay target: self selector: selector object: object1 object: object2 repeats: false]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector withObject: (id)object1 withObject: (id)object2 withObject: (id)object3 afterDelay: (OFTimeInterval)delay { void *pool = objc_autoreleasePoolPush(); [OFTimer scheduledTimerWithTimeInterval: delay target: self selector: selector object: object1 object: object2 object: object3 repeats: false]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector withObject: (id)object1 withObject: (id)object2 withObject: (id)object3 withObject: (id)object4 afterDelay: (OFTimeInterval)delay { void *pool = objc_autoreleasePoolPush(); [OFTimer scheduledTimerWithTimeInterval: delay target: self selector: selector object: object1 |
︙ | ︙ | |||
975 976 977 978 979 980 981 | [timer waitUntilDone]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread | | | | | | | 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 | [timer waitUntilDone]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread afterDelay: (OFTimeInterval)delay { void *pool = objc_autoreleasePoolPush(); [thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay target: self selector: selector repeats: false]]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (id)object afterDelay: (OFTimeInterval)delay { void *pool = objc_autoreleasePoolPush(); [thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay target: self selector: selector object: object repeats: false]]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (id)object1 withObject: (id)object2 afterDelay: (OFTimeInterval)delay { void *pool = objc_autoreleasePoolPush(); [thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay target: self selector: selector object: object1 object: object2 repeats: false]]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (id)object1 withObject: (id)object2 withObject: (id)object3 afterDelay: (OFTimeInterval)delay { void *pool = objc_autoreleasePoolPush(); [thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay target: self selector: selector object: object1 object: object2 object: object3 repeats: false]]; objc_autoreleasePoolPop(pool); } - (void)performSelector: (SEL)selector onThread: (OFThread *)thread withObject: (id)object1 withObject: (id)object2 withObject: (id)object3 withObject: (id)object4 afterDelay: (OFTimeInterval)delay { void *pool = objc_autoreleasePoolPush(); [thread.runLoop addTimer: [OFTimer timerWithTimeInterval: delay target: self selector: selector object: object1 |
︙ | ︙ | |||
1083 1084 1085 1086 1087 1088 1089 | { return (object == self); } - (unsigned long)hash { uintptr_t ptr = (uintptr_t)self; | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | | | | | 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 | { return (object == self); } - (unsigned long)hash { uintptr_t ptr = (uintptr_t)self; unsigned long hash; OFHashInit(&hash); for (size_t i = 0; i < sizeof(ptr); i++) { OFHashAdd(&hash, ptr & 0xFF); ptr >>= 8; } OFHashFinalize(&hash); return hash; } - (OFString *)description { /* Classes containing data should reimplement this! */ return [OFString stringWithFormat: @"<%@>", self.className]; } - (id)forwardingTargetForSelector: (SEL)selector { return nil; } - (void)doesNotRecognizeSelector: (SEL)selector { @throw [OFNotImplementedException exceptionWithSelector: selector object: self]; } - (instancetype)retain { #if defined(OF_HAVE_ATOMIC_OPS) OFAtomicIntIncrease(&PRE_IVARS->retainCount); #elif defined(OF_AMIGAOS) /* * On AmigaOS, we can only have one CPU. As increasing a variable is a * single instruction on M68K, we don't need Forbid() / Permit() on * M68K. */ # ifndef OF_AMIGAOS_M68K Forbid(); # endif PRE_IVARS->retainCount++; # ifndef OF_AMIGAOS_M68K Permit(); # endif #else OFEnsure(OFSpinlockLock(&PRE_IVARS->retainCountSpinlock) == 0); PRE_IVARS->retainCount++; OFEnsure(OFSpinlockUnlock(&PRE_IVARS->retainCountSpinlock) == 0); #endif return self; } - (unsigned int)retainCount { assert(PRE_IVARS->retainCount >= 0); return PRE_IVARS->retainCount; } - (void)release { #if defined(OF_HAVE_ATOMIC_OPS) OFReleaseMemoryBarrier(); if (OFAtomicIntDecrease(&PRE_IVARS->retainCount) <= 0) { OFAcquireMemoryBarrier(); [self dealloc]; } #elif defined(OF_AMIGAOS) int retainCount; Forbid(); retainCount = --PRE_IVARS->retainCount; Permit(); if (retainCount == 0) [self dealloc]; #else int retainCount; OFEnsure(OFSpinlockLock(&PRE_IVARS->retainCountSpinlock) == 0); retainCount = --PRE_IVARS->retainCount; OFEnsure(OFSpinlockUnlock(&PRE_IVARS->retainCountSpinlock) == 0); if (retainCount == 0) [self dealloc]; #endif } - (instancetype)autorelease |
︙ | ︙ | |||
1372 1373 1374 1375 1376 1377 1378 | [self retain]; return true; } - (void)dealloc { | < < < < < < < < < < < < < < < < < | 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 | [self retain]; return true; } - (void)dealloc { objc_destructInstance(self); free((char *)self - PRE_IVARS_ALIGN); } /* Required to use properties with the Apple runtime */ - (id)copyWithZone: (void *)zone { if OF_UNLIKELY (zone != NULL) { |
︙ | ︙ | |||
1416 1417 1418 1419 1420 1421 1422 | abort(); } return [(id)self mutableCopy]; } /* | | | > < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 | abort(); } return [(id)self mutableCopy]; } /* * The following are needed as the root class is the superclass of the root * class's metaclass and thus instance methods can be sent to class objects as * well. */ + (id)retain { return self; } + (id)autorelease { return self; } + (unsigned int)retainCount { return OFMaxRetainCount; } + (void)release { } + (void)dealloc |
︙ | ︙ |
Renamed and modified src/once.h [862d2c15bd] to src/OFOnce.h [3af1572f79].
1 | /* | < < | | | | | | | > > > > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "objfw-defs.h" #include "platform.h" #if defined(OF_HAVE_PTHREADS) # include <pthread.h> typedef pthread_once_t OFOnceControl; # define OFOnceControlInitValue PTHREAD_ONCE_INIT #elif defined(OF_HAVE_ATOMIC_OPS) typedef volatile int OFOnceControl; # define OFOnceControlInitValue 0 #elif defined(OF_AMIGAOS) || !defined(OF_HAVE_THREADS) typedef int OFOnceControl; # define OFOnceControlInitValue 0 #endif #ifdef __cplusplus extern "C" { #endif /** * @brief Executes the specified function exactly once in the application's * lifetime, even in a multi-threaded environment. * * @param control An OFOnceControl. This should be a static variable * preinitialized to `OFOnceControlInitValue`. * @param function The function to execute once */ extern void OFOnce(OFOnceControl *control, void (*function)(void)); #ifdef __cplusplus } #endif |
Renamed and modified src/once.m [dedad9ba7b] to src/OFOnce.m [72d5ba7049].
1 | /* | < < | | > > > > < < < < < | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdbool.h> #import "OFOnce.h" #if defined(OF_HAVE_THREADS) && defined(OF_HAVE_ATOMIC_OPS) # import "OFAtomic.h" # import "OFPlainMutex.h" #endif #ifdef OF_AMIGAOS # include <proto/exec.h> #endif void OFOnce(OFOnceControl *control, void (*function)(void)) { #if !defined(OF_HAVE_THREADS) if (*control == 0) { function(); *control = 1; } #elif defined(OF_HAVE_PTHREADS) pthread_once(control, function); #elif defined(OF_HAVE_ATOMIC_OPS) /* Avoid atomic operations in case it's already done. */ if (*control == 2) return; if (OFAtomicIntCompareAndSwap(control, 0, 1)) { function(); OFMemoryBarrier(); OFAtomicIntIncrease(control); } else while (*control == 1) OFYieldThread(); #elif defined(OF_AMIGAOS) bool run = false; /* Avoid Forbid() in case it's already done. */ if (*control == 2) return; |
︙ | ︙ | |||
74 75 76 77 78 79 80 | Forbid(); } } Permit(); if (run) { | | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | Forbid(); } } Permit(); if (run) { function(); *control = 2; } #else # error No OFOnce available #endif } |
Modified src/OFOptionsParser.h from [02d9a0ef41] to [14db018626].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | #import "OFString.h" @class OFMapTable; OF_ASSUME_NONNULL_BEGIN /** | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #import "OFString.h" @class OFMapTable; OF_ASSUME_NONNULL_BEGIN /** * @struct OFOptionsParserOption OFOptionsParser.h ObjFW/OFOptionsParser.h * * @brief An option which can be parsed by an @ref OFOptionsParser. */ typedef struct { /** The short version (e.g. `-v`) of the option or `\0` for none. */ OFUnichar shortOption; /** * The long version (e.g. `--verbose`) of the option or `nil` for none. */ OFString *__unsafe_unretained _Nullable longOption; /** |
︙ | ︙ | |||
55 56 57 58 59 60 61 | bool *_Nullable isSpecifiedPtr; /** * An optional pointer to an `OFString *` that is set to the * argument specified for the option or `nil` for no argument. */ OFString *__autoreleasing _Nullable *_Nullable argumentPtr; | < | | | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | bool *_Nullable isSpecifiedPtr; /** * An optional pointer to an `OFString *` that is set to the * argument specified for the option or `nil` for no argument. */ OFString *__autoreleasing _Nullable *_Nullable argumentPtr; } OFOptionsParserOption; /** * @class OFOptionsParser OFOptionsParser.h ObjFW/OFOptionsParser.h * * @brief A class for parsing the program options specified on the command line. */ OF_SUBCLASSING_RESTRICTED @interface OFOptionsParser: OFObject { OFOptionsParserOption *_options; OFMapTable *_longOptions; OFArray OF_GENERIC(OFString *) *_arguments; size_t _index, _subIndex; OFUnichar _lastOption; OFString *_Nullable _lastLongOption, *_Nullable _argument; bool _done; } /** * @brief The last parsed option. * * If @ref nextOption returned `?` or `:`, this returns the option which was * unknown or for which the argument was missing.@n * If this returns `-`, the last option is only available as a long option (see * lastLongOption). */ @property (readonly, nonatomic) OFUnichar lastOption; /** * @brief The long option for the last parsed option, or `nil` if the last * parsed option was not passed as a long option by the user. * * In case @ref nextOption returned `?`, this contains the unknown long * option.@n |
︙ | ︙ | |||
117 118 119 120 121 122 123 | */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFString *) *remainingArguments; /** * @brief Creates a new OFOptionsParser which accepts the specified options. * | | | | | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | */ @property (readonly, nonatomic) OFArray OF_GENERIC(OFString *) *remainingArguments; /** * @brief Creates a new OFOptionsParser which accepts the specified options. * * @param options An array of @ref OFOptionsParserOption specifying all * accepted options, terminated with an option whose short * option is `\0` and long option is `nil`. * * @return A new, autoreleased OFOptionsParser */ + (instancetype)parserWithOptions: (const OFOptionsParserOption *)options; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFOptionsParser so that it accepts * the specified options. * * @param options An array of @ref OFOptionsParserOption specifying all * accepted options, terminated with an option whose short * option is `\0` and long option is `nil`. * * @return An initialized OFOptionsParser */ - (instancetype)initWithOptions: (const OFOptionsParserOption *)options OF_DESIGNATED_INITIALIZER; /** * @brief Returns the next option. * * If the option is only available as a long option, `-` is returned. * Otherwise, the short option is returned, even if it was specified as a long * option.@n * If an unknown option is specified, `?` is returned.@n * If the argument for the option is missing, `:` is returned.@n * If there is an argument for the option even though it takes none, `=` is * returned.@n * If all options have been parsed, `\0` is returned. * * @note You need to call @ref nextOption repeatedly until it returns `\0` to * make sure all options have been parsed, even if you only rely on the * optional pointers specified and don't do any parsing yourself. * * @return The next option */ - (OFUnichar)nextOption; @end OF_ASSUME_NONNULL_END |
Modified src/OFOptionsParser.m from [194fc0cb2f] to [6586be74a2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
36 37 38 39 40 41 42 | return [(OFString *)object1 isEqual: (OFString *)object2]; } @implementation OFOptionsParser @synthesize lastOption = _lastOption, lastLongOption = _lastLongOption; @synthesize argument = _argument; | | | | | | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | return [(OFString *)object1 isEqual: (OFString *)object2]; } @implementation OFOptionsParser @synthesize lastOption = _lastOption, lastLongOption = _lastLongOption; @synthesize argument = _argument; + (instancetype)parserWithOptions: (const OFOptionsParserOption *)options { return [[[self alloc] initWithOptions: options] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithOptions: (const OFOptionsParserOption *)options { self = [super init]; @try { size_t count = 0; const OFOptionsParserOption *iter; OFOptionsParserOption *iter2; const OFMapTableFunctions keyFunctions = { .hash = stringHash, .equal = stringEqual }; const OFMapTableFunctions objectFunctions = { NULL }; /* Count, sanity check, initialize pointers */ for (iter = options; iter->shortOption != '\0' || iter->longOption != nil; iter++) { if (iter->hasArgument < -1 || iter->hasArgument > 1) @throw [OFInvalidArgumentException exception]; |
︙ | ︙ | |||
82 83 84 85 86 87 88 89 90 91 | *iter->isSpecifiedPtr = false; if (iter->argumentPtr) *iter->argumentPtr = nil; count++; } _longOptions = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions]; | > < < < | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | *iter->isSpecifiedPtr = false; if (iter->argumentPtr) *iter->argumentPtr = nil; count++; } _options = OFAllocMemory(count + 1, sizeof(*_options)); _longOptions = [[OFMapTable alloc] initWithKeyFunctions: keyFunctions objectFunctions: objectFunctions]; for (iter = options, iter2 = _options; iter->shortOption != '\0' || iter->longOption != nil; iter++, iter2++) { iter2->shortOption = iter->shortOption; iter2->longOption = nil; iter2->hasArgument = iter->hasArgument; |
︙ | ︙ | |||
140 141 142 143 144 145 146 | } return self; } - (void)dealloc { | < < < < | > > > | | | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | } return self; } - (void)dealloc { if (_options != NULL) for (OFOptionsParserOption *iter = _options; iter->shortOption != '\0' || iter->longOption != nil; iter++) [iter->longOption release]; OFFreeMemory(_options); [_longOptions release]; [_arguments release]; [_argument release]; [super dealloc]; } - (OFUnichar)nextOption { OFOptionsParserOption *iter; OFString *argument; if (_done || _index >= _arguments.count) return '\0'; [_lastLongOption release]; [_argument release]; |
︙ | ︙ | |||
187 188 189 190 191 192 193 | _index++; return '\0'; } if ([argument hasPrefix: @"--"]) { void *pool = objc_autoreleasePoolPush(); size_t pos; | | | | | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | _index++; return '\0'; } if ([argument hasPrefix: @"--"]) { void *pool = objc_autoreleasePoolPush(); size_t pos; OFOptionsParserOption *option; _lastOption = '-'; _index++; if ((pos = [argument rangeOfString: @"="].location) != OFNotFound) _argument = [[argument substringFromIndex: pos + 1] copy]; else pos = argument.length; _lastLongOption = [[argument substringWithRange: OFRangeMake(2, pos - 2)] copy]; objc_autoreleasePoolPop(pool); option = [_longOptions objectForKey: _lastLongOption]; if (option == NULL) return '?'; |
︙ | ︙ | |||
272 273 274 275 276 277 278 | return '?'; } - (OFArray *)remainingArguments { return [_arguments objectsInRange: | | | 267 268 269 270 271 272 273 274 275 276 | return '?'; } - (OFArray *)remainingArguments { return [_arguments objectsInRange: OFRangeMake(_index, _arguments.count - _index)]; } @end |
Renamed and modified src/pbkdf2.h [906ee7a0eb] to src/OFPBKDF2.h [fc763da9ca].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFHMAC; /** | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFHMAC; /** * @brief The parameters for @ref OFPBKDF2. */ typedef struct { /** @brief The HMAC to use to derive a key. */ __unsafe_unretained OFHMAC *HMAC; /** @brief The number of iterations to perform. */ size_t iterations; /** @brief The salt to derive a key with. */ const unsigned char *salt; /** @brief The length of the salt. */ |
︙ | ︙ | |||
52 53 54 55 56 57 58 | * @brief The desired length for the derived key. * * @ref key needs to have enough storage. */ size_t keyLength; /** @brief Whether data may be stored in swappable memory. */ bool allowsSwappableMemory; | | | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | * @brief The desired length for the derived key. * * @ref key needs to have enough storage. */ size_t keyLength; /** @brief Whether data may be stored in swappable memory. */ bool allowsSwappableMemory; } OFPBKDF2Parameters; #ifdef __cplusplus extern "C" { #endif /** * @brief Derives a key from a password and a salt using PBKDF2. * * @note This will call @ref OFHMAC::reset on the `HMAC` first, making it * possible to reuse the `HMAC`, but also meaning all previous results * from the `HMAC` get invalidated if they have not been copied. * * @param param The parameters to use */ extern void OFPBKDF2(OFPBKDF2Parameters param); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Renamed and modified src/pbkdf2.m [ae8f98e1e6] to src/OFPBKDF2.m [cca92e4a20].
1 | /* | < < | > < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdlib.h> #import "OFPBKDF2.h" #import "OFHMAC.h" #import "OFSecureData.h" #import "OFInvalidArgumentException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" void OFPBKDF2(OFPBKDF2Parameters param) { void *pool = objc_autoreleasePoolPush(); size_t blocks, digestSize = param.HMAC.digestSize; OFSecureData *buffer = [OFSecureData dataWithCount: digestSize allowsSwappableMemory: param.allowsSwappableMemory]; OFSecureData *digest = [OFSecureData |
︙ | ︙ | |||
57 58 59 60 61 62 63 | extendedSalt = [OFSecureData dataWithCount: param.saltLength + 4 allowsSwappableMemory: param.allowsSwappableMemory]; extendedSaltItems = extendedSalt.mutableItems; @try { | | > > | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | extendedSalt = [OFSecureData dataWithCount: param.saltLength + 4 allowsSwappableMemory: param.allowsSwappableMemory]; extendedSaltItems = extendedSalt.mutableItems; @try { uint32_t i = OFToBigEndian32(1); [param.HMAC setKey: param.password length: param.passwordLength]; memcpy(extendedSaltItems, param.salt, param.saltLength); while (param.keyLength > 0) { size_t length; memcpy(extendedSaltItems + param.saltLength, &i, 4); [param.HMAC reset]; [param.HMAC updateWithBuffer: extendedSaltItems length: param.saltLength + 4]; [param.HMAC calculate]; memcpy(bufferItems, param.HMAC.digest, digestSize); memcpy(digestItems, param.HMAC.digest, digestSize); for (size_t j = 1; j < param.iterations; j++) { [param.HMAC reset]; [param.HMAC updateWithBuffer: digestItems length: digestSize]; [param.HMAC calculate]; memcpy(digestItems, param.HMAC.digest, digestSize); for (size_t k = 0; k < digestSize; k++) bufferItems[k] ^= digestItems[k]; } length = digestSize; if (length > param.keyLength) length = param.keyLength; memcpy(param.key, bufferItems, length); param.key += length; param.keyLength -= length; i = OFToBigEndian32(OFFromBigEndian32(i) + 1); } } @catch (id e) { [extendedSalt zero]; [buffer zero]; [digest zero]; @throw e; } @finally { [param.HMAC zero]; } objc_autoreleasePoolPop(pool); } |
Modified src/OFPair.h from [b104780bae] to [96e09802be].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFPair.m from [6855a79df9] to [22c01e92c3].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
83 84 85 86 87 88 89 | return false; return true; } - (unsigned long)hash { | | | | | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, [_firstObject hash]); OFHashAddHash(&hash, [_secondObject hash]); OFHashFinalize(&hash); return hash; } - (id)copy { return [self retain]; |
︙ | ︙ |
Renamed and modified src/condition.h [ed39b78cbd] to src/OFPlainCondition.h [fd9b66a9ca].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #include "platform.h" #if !defined(OF_HAVE_THREADS) || \ (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS)) # error No conditions available! #endif | | < | | | | | | | | | > | | | | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #include "platform.h" #if !defined(OF_HAVE_THREADS) || \ (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS)) # error No conditions available! #endif /* For OFTimeInterval */ #import "OFObject.h" #import "OFPlainMutex.h" #if defined(OF_HAVE_PTHREADS) # include <pthread.h> typedef pthread_cond_t OFPlainCondition; #elif defined(OF_WINDOWS) # include <windows.h> typedef struct { HANDLE event; volatile int count; } OFPlainCondition; #elif defined(OF_AMIGAOS) # include <exec/tasks.h> typedef struct { struct OFPlainConditionWaitingTask { struct Task *task; unsigned char sigBit; struct OFPlainConditionWaitingTask *next; } *waitingTasks; } OFPlainCondition; #endif #ifdef __cplusplus extern "C" { #endif extern int OFPlainConditionNew(OFPlainCondition *condition); extern int OFPlainConditionSignal(OFPlainCondition *condition); extern int OFPlainConditionBroadcast(OFPlainCondition *condition); extern int OFPlainConditionWait(OFPlainCondition *condition, OFPlainMutex *mutex); extern int OFPlainConditionTimedWait(OFPlainCondition *condition, OFPlainMutex *mutex, OFTimeInterval timeout); #ifdef OF_AMIGAOS extern int OFPlainConditionWaitOrExecSignal(OFPlainCondition *condition, OFPlainMutex *mutex, ULONG *signalMask); extern int OFPlainConditionTimedWaitOrExecSignal(OFPlainCondition *condition, OFPlainMutex *mutex, OFTimeInterval timeout, ULONG *signalMask); #endif extern int OFPlainConditionFree(OFPlainCondition *condition); #ifdef __cplusplus } #endif |
Renamed and modified src/condition.m [f3cd7e798e] to src/OFPlainCondition.m [b7456714c7].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #if defined(OF_HAVE_PTHREADS) # include "platform/POSIX/OFPlainCondition.m" #elif defined(OF_WINDOWS) # include "platform/Windows/OFPlainCondition.m" #elif defined(OF_AMIGAOS) # include "platform/AmigaOS/OFPlainCondition.m" #endif |
Renamed and modified src/mutex.h [cbacd2f77f] to src/OFPlainMutex.h [e51d623af9].
1 | /* | < < | > > | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "objfw-defs.h" #include <errno.h> #include "platform.h" #if !defined(OF_HAVE_THREADS) || \ (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS)) # error No mutexes available! #endif #import "macros.h" #if defined(OF_HAVE_PTHREADS) # include <pthread.h> typedef pthread_mutex_t OFPlainMutex; #elif defined(OF_WINDOWS) # include <windows.h> typedef CRITICAL_SECTION OFPlainMutex; #elif defined(OF_AMIGAOS) # include <exec/semaphores.h> typedef struct SignalSemaphore OFPlainMutex; #endif #if defined(OF_HAVE_ATOMIC_OPS) # import "OFAtomic.h" typedef volatile int OFSpinlock; #elif defined(OF_HAVE_PTHREAD_SPINLOCKS) typedef pthread_spinlock_t OFSpinlock; #else typedef OFPlainMutex OFSpinlock; #endif #ifdef OF_HAVE_SCHED_YIELD # include <sched.h> #endif #if defined(OF_HAVE_RECURSIVE_PTHREAD_MUTEXES) || defined(OF_WINDOWS) || \ defined(OF_AMIGAOS) # define OFPlainRecursiveMutex OFPlainMutex #else # import "OFTLSKey.h" typedef struct { OFPlainMutex mutex; OFTLSKey count; } OFPlainRecursiveMutex; #endif #ifdef __cplusplus extern "C" { #endif extern int OFPlainMutexNew(OFPlainMutex *mutex); extern int OFPlainMutexLock(OFPlainMutex *mutex); extern int OFPlainMutexTryLock(OFPlainMutex *mutex); extern int OFPlainMutexUnlock(OFPlainMutex *mutex); extern int OFPlainMutexFree(OFPlainMutex *mutex); extern int OFPlainRecursiveMutexNew(OFPlainRecursiveMutex *rmutex); extern int OFPlainRecursiveMutexLock(OFPlainRecursiveMutex *rmutex); extern int OFPlainRecursiveMutexTryLock(OFPlainRecursiveMutex *rmutex); extern int OFPlainRecursiveMutexUnlock(OFPlainRecursiveMutex *rmutex); extern int OFPlainRecursiveMutexFree(OFPlainRecursiveMutex *rmutex); #ifdef __cplusplus } #endif /* Spinlocks are inlined for performance. */ static OF_INLINE void OFYieldThread(void) { #if defined(OF_HAVE_SCHED_YIELD) sched_yield(); #elif defined(OF_WINDOWS) Sleep(0); #endif } static OF_INLINE int OFSpinlockNew(OFSpinlock *spinlock) { #if defined(OF_HAVE_ATOMIC_OPS) *spinlock = 0; return 0; #elif defined(OF_HAVE_PTHREAD_SPINLOCKS) return pthread_spin_init(spinlock, 0); #else return OFPlainMutexNew(spinlock); #endif } static OF_INLINE int OFSpinlockTryLock(OFSpinlock *spinlock) { #if defined(OF_HAVE_ATOMIC_OPS) if (OFAtomicIntCompareAndSwap(spinlock, 0, 1)) { OFAcquireMemoryBarrier(); return 0; } return EBUSY; #elif defined(OF_HAVE_PTHREAD_SPINLOCKS) return pthread_spin_trylock(spinlock); #else return OFPlainMutexTryLock(spinlock); #endif } static OF_INLINE int OFSpinlockLock(OFSpinlock *spinlock) { #if defined(OF_HAVE_ATOMIC_OPS) size_t i; for (i = 0; i < 10; i++) if (OFSpinlockTryLock(spinlock) == 0) return 0; while (OFSpinlockTryLock(spinlock) == EBUSY) OFYieldThread(); return 0; #elif defined(OF_HAVE_PTHREAD_SPINLOCKS) return pthread_spin_lock(spinlock); #else return OFPlainMutexLock(spinlock); #endif } static OF_INLINE int OFSpinlockUnlock(OFSpinlock *spinlock) { #if defined(OF_HAVE_ATOMIC_OPS) bool ret = OFAtomicIntCompareAndSwap(spinlock, 1, 0); OFReleaseMemoryBarrier(); return (ret ? 0 : EINVAL); #elif defined(OF_HAVE_PTHREAD_SPINLOCKS) return pthread_spin_unlock(spinlock); #else return OFPlainMutexUnlock(spinlock); #endif } static OF_INLINE int OFSpinlockFree(OFSpinlock *spinlock) { #if defined(OF_HAVE_ATOMIC_OPS) return 0; #elif defined(OF_HAVE_PTHREAD_SPINLOCKS) return pthread_spin_destroy(spinlock); #else return OFPlainMutexFree(spinlock); #endif } |
Renamed and modified src/mutex.m [b45f1dde14] to src/OFPlainMutex.m [0367193fde].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #if defined(OF_HAVE_PTHREADS) # include "platform/POSIX/OFPlainMutex.m" #elif defined(OF_WINDOWS) # include "platform/Windows/OFPlainMutex.m" #elif defined(OF_AMIGAOS) # include "platform/AmigaOS/OFPlainMutex.m" #endif |
Renamed and modified src/thread.h [bf84b7cea6] to src/OFPlainThread.h [312286356e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | # error No threads available! #endif #import "macros.h" #if defined(OF_HAVE_PTHREADS) # include <pthread.h> | | | | | | > > > | > > > > > | > > > > | > > > > > | > | | | | | | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | # error No threads available! #endif #import "macros.h" #if defined(OF_HAVE_PTHREADS) # include <pthread.h> typedef pthread_t OFPlainThread; #elif defined(OF_WINDOWS) # include <windows.h> typedef HANDLE OFPlainThread; #elif defined(OF_AMIGAOS) # include <exec/tasks.h> # include <exec/semaphores.h> typedef struct { struct Task *task; void (*function)(id); id object; struct SignalSemaphore semaphore; struct Task *joinTask; unsigned char joinSigBit; bool detached, done; } *OFPlainThread; #endif typedef struct { float priority; size_t stackSize; } OFPlainThreadAttributes; #if defined(OF_HAVE_PTHREADS) static OF_INLINE OFPlainThread OFCurrentPlainThread(void) { return pthread_self(); } static OF_INLINE bool OFPlainThreadIsCurrent(OFPlainThread thread) { return pthread_equal(thread, pthread_self()); } #elif defined(OF_WINDOWS) static OF_INLINE OFPlainThread OFCurrentPlainThread(void) { return GetCurrentThread(); } static OF_INLINE bool OFPlainThreadIsCurrent(OFPlainThread thread) { return (thread == GetCurrentThread()); } #elif defined(OF_AMIGAOS) extern OFPlainThread OFCurrentPlainThread(void); extern bool OFPlainThreadIsCurrent(OFPlainThread); #endif #ifdef __cplusplus extern "C" { #endif extern int OFPlainThreadAttributesInit(OFPlainThreadAttributes *attr); extern int OFPlainThreadNew(OFPlainThread *thread, const char *name, void (*function)(id), id object, const OFPlainThreadAttributes *attr); extern void OFSetThreadName(const char *name); extern int OFPlainThreadJoin(OFPlainThread thread); extern int OFPlainThreadDetach(OFPlainThread thread); #ifdef __cplusplus } #endif |
Renamed and modified src/thread.m [5fe1003cc7] to src/OFPlainThread.m [ef8a973be8].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #if defined(OF_HAVE_PTHREADS) # include "platform/POSIX/OFPlainThread.m" #elif defined(OF_WINDOWS) # include "platform/Windows/OFPlainThread.m" #elif defined(OF_AMIGAOS) # include "platform/AmigaOS/OFPlainThread.m" #endif |
Modified src/OFPlugin.h from [f88f934be5] to [4badab4fb7].
1 | /* | < < | < < | < < | | > > | < | > > > | | | | > > | < > > | < > | | > > > > > > > > | < < | > > > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" @class OFString; #ifndef OF_WINDOWS # include <dlfcn.h> typedef void *OFPluginHandle; #else # include <windows.h> typedef HMODULE OFPluginHandle; #endif OF_ASSUME_NONNULL_BEGIN /** * @class OFPlugin OFPlugin.h ObjFW/OFPlugin.h * * @brief A class representing a loaded plugin (shared library). * */ OF_SUBCLASSING_RESTRICTED @interface OFPlugin: OFObject { OFPluginHandle _handle; } /** * @brief Returns the plugin path for a plugin with the specified name. * * E.g. on ELF systems, it appends .so, while on macOS and iOS, it creates the * appropriate plugin path. This can also be prefixed by a directory. * * @param name The name to return the plugin path for * @return The plugin path */ + (OFString *)pathForName: (OFString *)name; /** * @brief Creates a new OFPlugin by loading the plugin with the specified path. * * @param path The path to the plugin file. The suffix is appended * automatically. * @return An new, autoreleased OFPlugin */ + (instancetype)pluginWithPath: (OFString *)path; /** * @brief Initializes an already allocated OFPlugin by loading the plugin with * the specified path. * * @param path The path to the plugin file. The suffix is appended * automatically. * @return An initialized OFPlugin */ - (instancetype)initWithPath: (OFString *)path; /** * @brief Returns the address for the specified symbol, or `nil` if not found. * * @param symbol The symbol to return the address for * @return The address for the speccified symbol, or `nil` if not found */ - (nullable void *)addressForSymbol: (OFString *)symbol; @end OF_ASSUME_NONNULL_END |
Modified src/OFPlugin.m from [539230b0ba] to [dfbf2c9e77].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFLoadPluginFailedException.h" | | > > | | < | > | | < | | > > > | > | | < > > > > > | < | < < < < < < < < < < | < < < < < < < < < < | > > | > > | | | | < < | < < | < < < < < < | < < | | | | < < < < < < < | < < < < < < < < < | | | | | | > > > | > > > > > > | > > > | < < | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFLoadPluginFailedException.h" #ifndef RTLD_LAZY # define RTLD_LAZY 0 #endif @implementation OFPlugin + (instancetype)pluginWithPath: (OFString *)path { return [[[self alloc] initWithPath: path] autorelease]; } + (OFString *)pathForName: (OFString *)name { #if defined(OF_MACOS) return [name stringByAppendingFormat: @".bundle/Contents/MacOS/%@", name.lastPathComponent]; #elif defined(OF_IOS) return [name stringByAppendingFormat: @".bundle/%@", name.lastPathComponent]; #else return [name stringByAppendingString: @PLUGIN_SUFFIX]; #endif } - (instancetype)initWithPath: (OFString *)path { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); #ifndef OF_WINDOWS _handle = dlopen( [path cStringWithEncoding: [OFLocale encoding]], RTLD_LAZY); #else if ([OFSystemInfo isWindowsNT]) _handle = LoadLibraryW(path.UTF16String); else _handle = LoadLibraryA( [path cStringWithEncoding: [OFLocale encoding]]); #endif if (_handle == NULL) { #ifndef OF_WINDOWS OFString *error = [OFString stringWithCString: dlerror() encoding: [OFLocale encoding]]; #else OFString *error = nil; #endif @throw [OFLoadPluginFailedException exceptionWithPath: path error: error]; } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (void *)addressForSymbol: (OFString *)symbol { #ifndef OF_WINDOWS return dlsym(_handle, [symbol cStringWithEncoding: [OFLocale encoding]]); #else return (void *)(uintptr_t)GetProcAddress(_handle, [symbol cStringWithEncoding: [OFLocale encoding]]); #endif } - (void)dealloc { #ifndef OF_WINDOWS dlclose(_handle); #else FreeLibrary(_handle); #endif [super dealloc]; } @end |
Modified src/OFPointValue.h from [ef8036885e] to [42acb9db9a].
1 | /* | < < | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN @interface OFPointValue: OFValue { OFPoint _point; } - (instancetype)initWithPoint: (OFPoint)point; @end OF_ASSUME_NONNULL_END |
Modified src/OFPointValue.m from [83dd270a82] to [d80a9e47ec].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFPointValue @synthesize pointValue = _point; | | | | < | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFPointValue @synthesize pointValue = _point; - (instancetype)initWithPoint: (OFPoint)point { self = [super init]; _point = point; return self; } - (const char *)objCType { return @encode(OFPoint); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_point)) @throw [OFOutOfRangeException exception]; memcpy(value, &_point, sizeof(_point)); } - (OFString *)description { return [OFString stringWithFormat: @"<OFValue: OFPoint { %f, %f }>", _point.x, _point.y]; } @end |
Modified src/OFPointerValue.h from [3cdf748dae] to [9280ad762d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 | OF_ASSUME_NONNULL_BEGIN @interface OFPointerValue: OFValue { void *_pointer; } @end OF_ASSUME_NONNULL_END | > > | 17 18 19 20 21 22 23 24 25 26 27 28 | OF_ASSUME_NONNULL_BEGIN @interface OFPointerValue: OFValue { void *_pointer; } - (instancetype)initWithPointer: (const void *)pointer; @end OF_ASSUME_NONNULL_END |
Modified src/OFPointerValue.m from [2773c818f6] to [0b6a62e87f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
33 34 35 36 37 38 39 | } - (const char *)objCType { return @encode(void *); } | | < | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | } - (const char *)objCType { return @encode(void *); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_pointer)) @throw [OFOutOfRangeException exception]; memcpy(value, &_pointer, sizeof(_pointer)); } - (id)nonretainedObjectValue { return _pointer; } @end |
Modified src/OFPollKernelEventObserver.h from [0dbb6114a3] to [1b31db8247].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFPollKernelEventObserver.m from [5ca69d7bfc] to [458ef336b0].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 34 | #ifdef HAVE_POLL_H # include <poll.h> #endif #import "OFPollKernelEventObserver.h" #import "OFData.h" #import "OFObserveFailedException.h" #import "OFOutOfRangeException.h" | > < < < | > | < | | | | | | < | | | | < | | | | < | < < | < < | < < | < | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | #ifdef HAVE_POLL_H # include <poll.h> #endif #import "OFPollKernelEventObserver.h" #import "OFData.h" #import "OFSocket+Private.h" #import "OFObserveFailedException.h" #import "OFOutOfRangeException.h" #ifdef OF_WII # define pollfd pollsd # define fd socket #endif @implementation OFPollKernelEventObserver - (instancetype)init { self = [super init]; @try { struct pollfd p = { _cancelFD[0], POLLIN, 0 }; _FDs = [[OFMutableData alloc] initWithItemSize: sizeof(struct pollfd)]; [_FDs addItem: &p]; _maxFD = _cancelFD[0]; _FDToObject = OFAllocMemory((size_t)_maxFD + 1, sizeof(id)); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_FDs release]; OFFreeMemory(_FDToObject); [super dealloc]; } static void addObject(OFPollKernelEventObserver *self, id object, int fd, short events) { struct pollfd *FDs; size_t count; bool found; if (fd < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: EBADF]; FDs = self->_FDs.mutableItems; count = self->_FDs.count; found = false; for (size_t i = 0; i < count; i++) { if (FDs[i].fd == fd) { FDs[i].events |= events; found = true; break; } } if (!found) { struct pollfd p = { fd, events, 0 }; if (fd > self->_maxFD) { self->_maxFD = fd; self->_FDToObject = OFResizeMemory(self->_FDToObject, (size_t)self->_maxFD + 1, sizeof(id)); } self->_FDToObject[fd] = object; [self->_FDs addItem: &p]; } } static void removeObject(OFPollKernelEventObserver *self, id object, int fd, short events) { struct pollfd *FDs; size_t nFDs; if (fd < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: EBADF]; FDs = self->_FDs.mutableItems; nFDs = self->_FDs.count; for (size_t i = 0; i < nFDs; i++) { if (FDs[i].fd == fd) { FDs[i].events &= ~events; if (FDs[i].events == 0) { /* * TODO: Remove from and resize _FDToObject, * adjust _maxFD. */ [self->_FDs removeItemAtIndex: i]; } break; } } } - (void)addObjectForReading: (id <OFReadyForReadingObserving>)object { addObject(self, object, object.fileDescriptorForReading, POLLIN); [super addObjectForReading: object]; } - (void)addObjectForWriting: (id <OFReadyForWritingObserving>)object { addObject(self, object, object.fileDescriptorForWriting, POLLOUT); [super addObjectForWriting: object]; } - (void)removeObjectForReading: (id <OFReadyForReadingObserving>)object { removeObject(self, object, object.fileDescriptorForReading, POLLIN); [super removeObjectForReading: object]; } - (void)removeObjectForWriting: (id <OFReadyForWritingObserving>)object { removeObject(self, object, object.fileDescriptorForWriting, POLLOUT); [super removeObjectForWriting: object]; } - (void)observeForTimeInterval: (OFTimeInterval)timeInterval { void *pool; struct pollfd *FDs; int events; size_t nFDs; if ([self of_processReadBuffers]) |
︙ | ︙ | |||
208 209 210 211 212 213 214 | if (FDs[i].revents & POLLIN) { void *pool2; if (FDs[i].fd == _cancelFD[0]) { char buffer; #ifdef OF_HAVE_PIPE | | | | | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | if (FDs[i].revents & POLLIN) { void *pool2; if (FDs[i].fd == _cancelFD[0]) { char buffer; #ifdef OF_HAVE_PIPE OFEnsure(read(_cancelFD[0], &buffer, 1) == 1); #else OFEnsure(recvfrom(_cancelFD[0], &buffer, 1, 0, NULL, NULL) == 1); #endif FDs[i].revents = 0; continue; } pool2 = objc_autoreleasePoolPush(); |
︙ | ︙ |
Modified src/OFRIPEMD160Hash.h from [2ffc431b34] to [6a4a8d87d4].
1 | /* | < < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFCryptographicHash.h" OF_ASSUME_NONNULL_BEGIN @class OFSecureData; /** * @class OFRIPEMD160Hash OFRIPEMD160Hash.h ObjFW/OFRIPEMD160Hash.h * * @brief A class which provides methods to create a RIPEMD-160 hash. */ OF_SUBCLASSING_RESTRICTED @interface OFRIPEMD160Hash: OFObject <OFCryptographicHash> { OFSecureData *_iVarsData; struct { uint32_t state[5]; uint64_t bits; union { unsigned char bytes[64]; uint32_t words[16]; } buffer; size_t bufferLength; } *_iVars; bool _allowsSwappableMemory; bool _calculated; } @end OF_ASSUME_NONNULL_END |
Modified src/OFRIPEMD160Hash.m from [f5c31d29f5] to [a6c68d768d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 | #include <string.h> #import "OFRIPEMD160Hash.h" #import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFOutOfRangeException.h" | > < | > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <string.h> #import "OFRIPEMD160Hash.h" #import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFHashNotCalculatedException.h" #import "OFOutOfRangeException.h" static const size_t digestSize = 20; static const size_t blockSize = 64; OF_DIRECT_MEMBERS @interface OFRIPEMD160Hash () - (void)of_resetState; @end #define F(a, b, c) ((a) ^ (b) ^ (c)) |
︙ | ︙ | |||
69 70 71 72 73 74 75 | }; static OF_INLINE void byteSwapVectorIfBE(uint32_t *vector, uint_fast8_t length) { #ifdef OF_BIG_ENDIAN for (uint_fast8_t i = 0; i < length; i++) | | | | | | | | | | | | | | | | | | | | | | | | | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | }; static OF_INLINE void byteSwapVectorIfBE(uint32_t *vector, uint_fast8_t length) { #ifdef OF_BIG_ENDIAN for (uint_fast8_t i = 0; i < length; i++) vector[i] = OFByteSwap32(vector[i]); #endif } static void processBlock(uint32_t *state, uint32_t *buffer) { uint32_t new[5], new2[5]; uint_fast8_t i = 0; new[0] = new2[0] = state[0]; new[1] = new2[1] = state[1]; new[2] = new2[2] = state[2]; new[3] = new2[3] = state[3]; new[4] = new2[4] = state[4]; byteSwapVectorIfBE(buffer, 16); #define LOOP_BODY(f, g, k, k2) \ { \ uint32_t tmp; \ \ tmp = new[0] + f(new[1], new[2], new[3]) + \ buffer[wordOrder[i]] + k; \ tmp = OFRotateLeft(tmp, rotateBits[i]) + new[4]; \ \ new[0] = new[4]; \ new[4] = new[3]; \ new[3] = OFRotateLeft(new[2], 10); \ new[2] = new[1]; \ new[1] = tmp; \ \ tmp = new2[0] + g(new2[1], new2[2], new2[3]) + \ buffer[wordOrder2[i]] + k2; \ tmp = OFRotateLeft(tmp, rotateBits2[i]) + new2[4]; \ \ new2[0] = new2[4]; \ new2[4] = new2[3]; \ new2[3] = OFRotateLeft(new2[2], 10); \ new2[2] = new2[1]; \ new2[1] = tmp; \ } for (; i < 16; i++) LOOP_BODY(F, J, 0x00000000, 0x50A28BE6) for (; i < 32; i++) LOOP_BODY(G, I, 0x5A827999, 0x5C4DD124) for (; i < 48; i++) |
︙ | ︙ | |||
139 140 141 142 143 144 145 | @implementation OFRIPEMD160Hash @synthesize calculated = _calculated; @synthesize allowsSwappableMemory = _allowsSwappableMemory; + (size_t)digestSize { | | | | | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | @implementation OFRIPEMD160Hash @synthesize calculated = _calculated; @synthesize allowsSwappableMemory = _allowsSwappableMemory; + (size_t)digestSize { return digestSize; } + (size_t)blockSize { return blockSize; } + (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory { return [[[self alloc] initWithAllowsSwappableMemory: allowsSwappableMemory] autorelease]; } - (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory { |
︙ | ︙ | |||
192 193 194 195 196 197 198 | [_iVarsData release]; [super dealloc]; } - (size_t)digestSize { | | | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | [_iVarsData release]; [super dealloc]; } - (size_t)digestSize { return digestSize; } - (size_t)blockSize { return blockSize; } - (id)copy { OFRIPEMD160Hash *copy = [[OFRIPEMD160Hash alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; |
︙ | ︙ | |||
221 222 223 224 225 226 227 | _iVars->state[0] = 0x67452301; _iVars->state[1] = 0xEFCDAB89; _iVars->state[2] = 0x98BADCFE; _iVars->state[3] = 0x10325476; _iVars->state[4] = 0xC3D2E1F0; } | | < | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | _iVars->state[0] = 0x67452301; _iVars->state[1] = 0xEFCDAB89; _iVars->state[2] = 0x98BADCFE; _iVars->state[3] = 0x10325476; _iVars->state[4] = 0xC3D2E1F0; } - (void)updateWithBuffer: (const void *)buffer_ length: (size_t)length { const unsigned char *buffer = buffer_; if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; |
︙ | ︙ | |||
257 258 259 260 261 262 263 | _iVars->bufferLength = 0; } } } - (const unsigned char *)digest { | | > > | | > > > > > > > | | | | | < < | | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | _iVars->bufferLength = 0; } } } - (const unsigned char *)digest { if (!_calculated) @throw [OFHashNotCalculatedException exceptionWithObject: self]; return (const unsigned char *)_iVars->state; } - (void)calculate { if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; _iVars->buffer.bytes[_iVars->bufferLength] = 0x80; OFZeroMemory(_iVars->buffer.bytes + _iVars->bufferLength + 1, 64 - _iVars->bufferLength - 1); if (_iVars->bufferLength >= 56) { processBlock(_iVars->state, _iVars->buffer.words); OFZeroMemory(_iVars->buffer.bytes, 64); } _iVars->buffer.words[14] = OFToLittleEndian32((uint32_t)(_iVars->bits & 0xFFFFFFFF)); _iVars->buffer.words[15] = OFToLittleEndian32((uint32_t)(_iVars->bits >> 32)); processBlock(_iVars->state, _iVars->buffer.words); OFZeroMemory(&_iVars->buffer, sizeof(_iVars->buffer)); byteSwapVectorIfBE(_iVars->state, 5); _calculated = true; } - (void)reset { [self of_resetState]; _iVars->bits = 0; OFZeroMemory(&_iVars->buffer, sizeof(_iVars->buffer)); _iVars->bufferLength = 0; _calculated = false; } @end |
Modified src/OFRangeCharacterSet.h from [037c8088c6] to [c903dba907].
1 | /* | < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFCharacterSet.h" OF_ASSUME_NONNULL_BEGIN @interface OFRangeCharacterSet: OFCharacterSet { OFRange _range; } @end OF_ASSUME_NONNULL_END |
Modified src/OFRangeCharacterSet.m from [bec25adcc7] to [4870541066].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | @implementation OFRangeCharacterSet - (instancetype)init { OF_INVALID_INIT_METHOD } | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | @implementation OFRangeCharacterSet - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithRange: (OFRange)range { self = [super init]; @try { if (SIZE_MAX - range.location < range.length) @throw [OFOutOfRangeException exception]; _range = range; } @catch (id e) { [self release]; @throw e; } return self; } - (bool)characterIsMember: (OFUnichar)character { return (character >= _range.location && character < _range.location + _range.length); } @end |
Modified src/OFRangeValue.h from [085216fa6c] to [3251ae1de3].
1 | /* | < < | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN @interface OFRangeValue: OFValue { OFRange _range; } - (instancetype)initWithRange: (OFRange)range; @end OF_ASSUME_NONNULL_END |
Modified src/OFRangeValue.m from [36416bfa67] to [72e3ffee04].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFRangeValue @synthesize rangeValue = _range; | | | | < | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFRangeValue @synthesize rangeValue = _range; - (instancetype)initWithRange: (OFRange)range { self = [super init]; _range = range; return self; } - (const char *)objCType { return @encode(OFRange); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_range)) @throw [OFOutOfRangeException exception]; memcpy(value, &_range, sizeof(_range)); } - (OFString *)description { return [OFString stringWithFormat: @"<OFValue: OFRange { %zu, %zu }>", _range.location, _range.length]; } @end |
Renamed and modified src/OFRectangleValue.h [2ca7936a53] to src/OFRectValue.h [83e8354a4a].
1 | /* | < < | | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN @interface OFRectValue: OFValue { OFRect _rect; } - (instancetype)initWithRect: (OFRect)rect; @end OF_ASSUME_NONNULL_END |
Renamed and modified src/OFRectangleValue.m [ed79263f8b] to src/OFRectValue.m [0064a9b262].
1 | /* | < < | | | | | | | | < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFRectValue.h" #import "OFMethodSignature.h" #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFRectValue @synthesize rectValue = _rect; - (instancetype)initWithRect: (OFRect)rect { self = [super init]; _rect = rect; return self; } - (const char *)objCType { return @encode(OFRect); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_rect)) @throw [OFOutOfRangeException exception]; memcpy(value, &_rect, sizeof(_rect)); } - (OFString *)description { return [OFString stringWithFormat: @"<OFValue: OFRect { %f, %f, %f, %f }>", _rect.origin.x, _rect.origin.y, _rect.size.width, _rect.size.height]; } @end |
Modified src/OFRecursiveMutex.h from [ebcc3c2a34] to [5662e5ef58].
1 | /* | < < | < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFLocking.h" #import "OFPlainMutex.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFRecursiveMutex OFRecursiveMutex.h ObjFW/OFRecursiveMutex.h * * @brief A class for creating mutual exclusions which can be entered * recursively. */ OF_SUBCLASSING_RESTRICTED @interface OFRecursiveMutex: OFObject <OFLocking> { OFPlainRecursiveMutex _rmutex; bool _initialized; OFString *_Nullable _name; } /** * @brief Creates a new recursive mutex. * * @return A new autoreleased recursive mutex. */ + (instancetype)mutex; @end OF_ASSUME_NONNULL_END |
Modified src/OFRecursiveMutex.m from [3739c89b37] to [cb58226e3c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
35 36 37 38 39 40 41 | return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; | | > | > | > | > | > | > | | > | > | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; if (OFPlainRecursiveMutexNew(&_rmutex) != 0) { Class c = self.class; [self release]; @throw [OFInitializationFailedException exceptionWithClass: c]; } _initialized = true; return self; } - (void)dealloc { if (_initialized) { int error = OFPlainRecursiveMutexFree(&_rmutex); if (error != 0) { OFEnsure(error == EBUSY); @throw [OFStillLockedException exceptionWithLock: self]; } } [_name release]; [super dealloc]; } - (void)lock { int error = OFPlainRecursiveMutexLock(&_rmutex); if (error != 0) @throw [OFLockFailedException exceptionWithLock: self errNo: error]; } - (bool)tryLock { int error = OFPlainRecursiveMutexTryLock(&_rmutex); if (error != 0) { if (error == EBUSY) return false; else @throw [OFLockFailedException exceptionWithLock: self errNo: error]; } return true; } - (void)unlock { int error = OFPlainRecursiveMutexUnlock(&_rmutex); if (error != 0) @throw [OFUnlockFailedException exceptionWithLock: self errNo: error]; } - (OFString *)description { if (_name == nil) return super.description; return [OFString stringWithFormat: @"<%@: %@>", self.className, _name]; } @end |
Modified src/OFRunLoop+Private.h from [979d7c9f7e] to [1af8d65653].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | @interface OFRunLoop () + (void)of_setMainRunLoop: (OFRunLoop *)runLoop; #ifdef OF_HAVE_SOCKETS + (void)of_addAsyncReadForStream: (OFStream <OFReadyForReadingObserving> *) stream buffer: (void *)buffer length: (size_t)length | | | | | | | | < < | | < | | | < < | | | | | | | | | | | | < | < | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | @interface OFRunLoop () + (void)of_setMainRunLoop: (OFRunLoop *)runLoop; #ifdef OF_HAVE_SOCKETS + (void)of_addAsyncReadForStream: (OFStream <OFReadyForReadingObserving> *) stream buffer: (void *)buffer length: (size_t)length mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (nullable OFStreamAsyncReadBlock)block # endif delegate: (nullable id <OFStreamDelegate>)delegate; + (void)of_addAsyncReadForStream: (OFStream <OFReadyForReadingObserving> *) stream buffer: (void *)buffer exactLength: (size_t)length mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (nullable OFStreamAsyncReadBlock)block # endif delegate: (nullable id <OFStreamDelegate>)delegate; + (void)of_addAsyncReadLineForStream: (OFStream <OFReadyForReadingObserving> *) stream encoding: (OFStringEncoding)encoding mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (nullable OFStreamAsyncReadLineBlock)block # endif delegate: (nullable id <OFStreamDelegate>)delegate; + (void)of_addAsyncWriteForStream: (OFStream <OFReadyForWritingObserving> *) stream data: (OFData *)data mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (nullable OFStreamAsyncWriteDataBlock)block # endif delegate: (nullable id <OFStreamDelegate>)delegate; + (void)of_addAsyncWriteForStream: (OFStream <OFReadyForWritingObserving> *) stream string: (OFString *)string encoding: (OFStringEncoding)encoding mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (nullable OFStreamAsyncWriteStringBlock)block # endif delegate: (nullable id <OFStreamDelegate>)delegate; # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) + (void)of_addAsyncConnectForSocket: (id)socket mode: (OFRunLoopMode)mode delegate: (id <OFRunLoopConnectDelegate>)delegate; # endif + (void)of_addAsyncAcceptForSocket: (id)socket mode: (OFRunLoopMode)mode block: (nullable id)block delegate: (nullable id)delegate; + (void)of_addAsyncReceiveForDatagramSocket: (OFDatagramSocket *)socket buffer: (void *)buffer length: (size_t)length mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (nullable OFDatagramSocketAsyncReceiveBlock)block # endif delegate: (nullable id <OFDatagramSocketDelegate>) delegate; + (void)of_addAsyncSendForDatagramSocket: (OFDatagramSocket *)socket data: (OFData *)data receiver: (const OFSocketAddress *)receiver mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (nullable OFDatagramSocketAsyncSendDataBlock)block # endif delegate: (nullable id <OFDatagramSocketDelegate>)delegate; + (void)of_addAsyncReceiveForSequencedPacketSocket: (OFSequencedPacketSocket *)socket buffer: (void *)buffer length: (size_t)length mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (nullable OFSequencedPacketSocketAsyncReceiveBlock)block # endif delegate: (nullable id <OFSequencedPacketSocketDelegate>) delegate; + (void)of_addAsyncSendForSequencedPacketSocket: (OFSequencedPacketSocket *)socket data: (OFData *)data mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (nullable OFSequencedPacketSocketAsyncSendDataBlock)block # endif delegate: (nullable id <OFSequencedPacketSocketDelegate>)delegate; + (void)of_cancelAsyncRequestsForObject: (id)object mode: (OFRunLoopMode)mode; #endif - (void)of_removeTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode; @end OF_ASSUME_NONNULL_END |
Modified src/OFRunLoop.h from [0cb286823e] to [e058e5f18b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFTimer; @class OFDate; /** * @brief A mode for an OFRunLoop. */ | | | | | < | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFTimer; @class OFDate; /** * @brief A mode for an OFRunLoop. */ typedef OFConstantString *OFRunLoopMode; #ifdef __cplusplus extern "C" { #endif /** * @brief The default mode for an OFRunLoop. */ extern const OFRunLoopMode OFDefaultRunLoopMode; #ifdef __cplusplus } #endif /** * @class OFRunLoop OFRunLoop.h ObjFW/OFRunLoop.h * * @brief A class providing a run loop for the application and its processes. */ OF_SUBCLASSING_RESTRICTED @interface OFRunLoop: OFObject { OFMutableDictionary *_states; #ifdef OF_HAVE_THREADS OFMutex *_statesMutex; #endif OFRunLoopMode _Nullable _currentMode; volatile bool _stop; } #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nullable, nonatomic) OFRunLoop *mainRunLoop; @property (class, readonly, nullable, nonatomic) OFRunLoop *currentRunLoop; #endif @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFRunLoopMode currentMode; /** * @brief Returns the run loop for the main thread. * * @return The run loop for the main thread */ + (nullable OFRunLoop *)mainRunLoop; |
︙ | ︙ | |||
100 101 102 103 104 105 106 | /** * @brief Adds an OFTimer to the run loop for the specified mode. * * @param timer The timer to add * @param mode The run loop mode in which to run the timer */ | | < | < < | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | /** * @brief Adds an OFTimer to the run loop for the specified mode. * * @param timer The timer to add * @param mode The run loop mode in which to run the timer */ - (void)addTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode; #ifdef OF_AMIGAOS /** * @brief Adds an Exec Signal to the run loop. * * If a signal is added multiple times, the specified methods will be performed * in the order added. * * @note This is only available on AmigaOS! * * @param signal The signal to add * @param target The target to call when the signal was received * @param selector The selector to call on the target when the signal was * received. The selector must have one parameter for the ULONG * of the signal that was received. */ - (void)addExecSignal: (ULONG)signal target: (id)target selector: (SEL)selector; /** * @brief Adds an Exec Signal to the run loop for the specified mode. * * If a signal is added multiple times, the specified methods will be performed * in the order added. * * @note This is only available on AmigaOS! * * @param signal The signal to add * @param mode The run loop mode in which to handle the signal * @param target The target to call when the signal was received * @param selector The selector to call on the target when the signal was * received. The selector must have one parameter for the ULONG * of the signal that was received. */ - (void)addExecSignal: (ULONG)signal forMode: (OFRunLoopMode)mode target: (id)target selector: (SEL)selector; /** * @brief Removes the specified Exec Signal with the specified target and * selector. * |
︙ | ︙ | |||
164 165 166 167 168 169 170 | * * @param signal The signal to remove * @param mode The run loop mode to which the signal was added * @param target The target which was specified when adding the signal * @param selector The selector which was specified when adding the signal */ - (void)removeExecSignal: (ULONG)signal | | | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | * * @param signal The signal to remove * @param mode The run loop mode to which the signal was added * @param target The target which was specified when adding the signal * @param selector The selector which was specified when adding the signal */ - (void)removeExecSignal: (ULONG)signal forMode: (OFRunLoopMode)mode target: (id)target selector: (SEL)selector; #endif /** * @brief Starts the run loop. */ |
︙ | ︙ | |||
188 189 190 191 192 193 194 | /** * @brief Run the run loop until an event or timer occurs or the specified * deadline is reached. * * @param mode The mode in which to run the run loop * @param deadline The date until which the run loop should run at the longest */ | < | | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | /** * @brief Run the run loop until an event or timer occurs or the specified * deadline is reached. * * @param mode The mode in which to run the run loop * @param deadline The date until which the run loop should run at the longest */ - (void)runMode: (OFRunLoopMode)mode beforeDate: (nullable OFDate *)deadline; /** * @brief Stops the run loop. If there is still an operation being executed, it * is finished before the run loop stops. */ - (void)stop; @end OF_ASSUME_NONNULL_END |
Modified src/OFRunLoop.m from [ae4dcb6d52] to [e671b17f7b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
40 41 42 43 44 45 46 47 | #endif #import "OFSortedList.h" #import "OFTimer.h" #import "OFTimer+Private.h" #import "OFDate.h" #import "OFObserveFailedException.h" | > > | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #endif #import "OFSortedList.h" #import "OFTimer.h" #import "OFTimer+Private.h" #import "OFDate.h" #import "OFObserveFailedException.h" #import "OFWriteFailedException.h" #include "OFRunLoopConstants.inc" static OFRunLoop *mainRunLoop = nil; @interface OFRunLoopState: OFObject #ifdef OF_HAVE_SOCKETS <OFKernelEventObserverDelegate> #endif { |
︙ | ︙ | |||
74 75 76 77 78 79 80 | # ifdef OF_HAVE_THREADS OFMutex *_execSignalsMutex; # endif #endif } @end | < < < < < < | | | | | | | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | # ifdef OF_HAVE_THREADS OFMutex *_execSignalsMutex; # endif #endif } @end #ifdef OF_HAVE_SOCKETS @interface OFRunLoopQueueItem: OFObject { @public id _delegate; } - (bool)handleObject: (id)object; @end @interface OFRunLoopReadQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS OFStreamAsyncReadBlock _block; # endif void *_buffer; size_t _length; } @end @interface OFRunLoopExactReadQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS OFStreamAsyncReadBlock _block; # endif void *_buffer; size_t _exactLength, _readLength; } @end @interface OFRunLoopReadLineQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS OFStreamAsyncReadLineBlock _block; # endif OFStringEncoding _encoding; } @end @interface OFRunLoopWriteDataQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS OFStreamAsyncWriteDataBlock _block; # endif OFData *_data; size_t _writtenLength; } @end @interface OFRunLoopWriteStringQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS OFStreamAsyncWriteStringBlock _block; # endif OFString *_string; OFStringEncoding _encoding; size_t _writtenLength; } @end # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) @interface OFRunLoopConnectQueueItem: OFRunLoopQueueItem @end |
︙ | ︙ | |||
163 164 165 166 167 168 169 | } @end @interface OFRunLoopDatagramReceiveQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS | | | | | | | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | } @end @interface OFRunLoopDatagramReceiveQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS OFDatagramSocketAsyncReceiveBlock _block; # endif void *_buffer; size_t _length; } @end @interface OFRunLoopDatagramSendQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS OFDatagramSocketAsyncSendDataBlock _block; # endif OFData *_data; OFSocketAddress _receiver; } @end @interface OFRunLoopPacketReceiveQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS OFSequencedPacketSocketAsyncReceiveBlock _block; # endif void *_buffer; size_t _length; } @end @interface OFRunLoopPacketSendQueueItem: OFRunLoopQueueItem { @public # ifdef OF_HAVE_BLOCKS OFSequencedPacketSocketAsyncSendDataBlock _block; # endif OFData *_data; } @end #endif @implementation OFRunLoopState |
︙ | ︙ | |||
280 281 282 283 284 285 286 | OFList OF_GENERIC(OF_KINDOF(OFRunLoopReadQueueItem *)) *queue = [[_readQueues objectForKey: object] retain]; assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { | | | > | | | 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | OFList OF_GENERIC(OF_KINDOF(OFRunLoopReadQueueItem *)) *queue = [[_readQueues objectForKey: object] retain]; assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { OFListItem listItem = queue.firstListItem; /* * The handler might have called -[cancelAsyncRequests] * so that our queue is now empty, in which case we * should do nothing. */ if (listItem != NULL) { /* * Make sure we keep the target until after we * are done removing the object. The reason for * this is that the target might call * -[cancelAsyncRequests] in its dealloc. */ [[OFListItemObject(listItem) retain] autorelease]; [queue removeListItem: listItem]; if (queue.count == 0) { [_kernelEventObserver removeObjectForReading: object]; [_readQueues removeObjectForKey: object]; } |
︙ | ︙ | |||
323 324 325 326 327 328 329 | */ OFList *queue = [[_writeQueues objectForKey: object] retain]; assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { | | | > | | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | */ OFList *queue = [[_writeQueues objectForKey: object] retain]; assert(queue != nil); @try { if (![queue.firstObject handleObject: object]) { OFListItem listItem = queue.firstListItem; /* * The handler might have called -[cancelAsyncRequests] * so that our queue is now empty, in which case we * should do nothing. */ if (listItem != NULL) { /* * Make sure we keep the target until after we * are done removing the object. The reason for * this is that the target might call * -[cancelAsyncRequests] in its dealloc. */ [[OFListItemObject(listItem) retain] autorelease]; [queue removeListItem: listItem]; if (queue.count == 0) { [_kernelEventObserver removeObjectForWriting: object]; [_writeQueues removeObjectForKey: object]; } |
︙ | ︙ | |||
427 428 429 430 431 432 433 | @implementation OFRunLoopReadQueueItem - (bool)handleObject: (id)object { size_t length; id exception = nil; @try { | | < | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | @implementation OFRunLoopReadQueueItem - (bool)handleObject: (id)object { size_t length; id exception = nil; @try { length = [object readIntoBuffer: _buffer length: _length]; } @catch (id e) { length = 0; exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) |
︙ | ︙ | |||
571 572 573 574 575 576 577 | size_t length; id exception = nil; size_t dataLength = _data.count * _data.itemSize; OFData *newData, *oldData; @try { const char *dataItems = _data.items; | | | > > | > > > | | 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 | size_t length; id exception = nil; size_t dataLength = _data.count * _data.itemSize; OFData *newData, *oldData; @try { const char *dataItems = _data.items; length = dataLength - _writtenLength; [object writeBuffer: dataItems + _writtenLength length: length]; } @catch (OFWriteFailedException *e) { length = e.bytesWritten; if (e.errNo != EWOULDBLOCK && e.errNo != EAGAIN) exception = e; } @catch (id e) { length = 0; exception = e; } _writtenLength += length; OFEnsure(_writtenLength <= dataLength); if (_writtenLength != dataLength && exception == nil) return true; # ifdef OF_HAVE_BLOCKS if (_block != NULL) { newData = _block(_writtenLength, exception); if (newData == nil) return false; oldData = _data; _data = [newData copy]; [oldData release]; |
︙ | ︙ | |||
643 644 645 646 647 648 649 | size_t length; id exception = nil; size_t cStringLength = [_string cStringLengthWithEncoding: _encoding]; OFString *newString, *oldString; @try { const char *cString = [_string cStringWithEncoding: _encoding]; | | | > > | > > > | | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 | size_t length; id exception = nil; size_t cStringLength = [_string cStringLengthWithEncoding: _encoding]; OFString *newString, *oldString; @try { const char *cString = [_string cStringWithEncoding: _encoding]; length = cStringLength - _writtenLength; [object writeBuffer: cString + _writtenLength length: length]; } @catch (OFWriteFailedException *e) { length = e.bytesWritten; if (e.errNo != EWOULDBLOCK && e.errNo != EAGAIN) exception = e; } @catch (id e) { length = 0; exception = e; } _writtenLength += length; OFEnsure(_writtenLength <= cStringLength); if (_writtenLength != cStringLength && exception == nil) return true; # ifdef OF_HAVE_BLOCKS if (_block != NULL) { newString = _block(_writtenLength, exception); if (newString == nil) return false; oldString = _string; _string = [newString copy]; [oldString release]; |
︙ | ︙ | |||
736 737 738 739 740 741 742 | timerWithTimeInterval: 0 target: _delegate selector: @selector(of_socketDidConnect: exception:) object: object object: exception repeats: false]; | < | < | 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 | timerWithTimeInterval: 0 target: _delegate selector: @selector(of_socketDidConnect: exception:) object: object object: exception repeats: false]; [runLoop addTimer: timer forMode: runLoop.currentMode]; } return false; } @end # endif |
︙ | ︙ | |||
761 762 763 764 765 766 767 | acceptedSocket = nil; exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { if ([object isKindOfClass: [OFStreamSocket class]]) | | | | < | | 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 | acceptedSocket = nil; exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { if ([object isKindOfClass: [OFStreamSocket class]]) return ((OFStreamSocketAsyncAcceptBlock)_block)( acceptedSocket, exception); else if ([object isKindOfClass: [OFSequencedPacketSocket class]]) return ((OFSequencedPacketSocketAsyncAcceptBlock) _block)(acceptedSocket, exception); else OFEnsure(0); } else { # endif if (![_delegate respondsToSelector: @selector(socket:didAcceptSocket:exception:)]) return false; return [_delegate socket: object |
︙ | ︙ | |||
798 799 800 801 802 803 804 | # endif @end @implementation OFRunLoopDatagramReceiveQueueItem - (bool)handleObject: (id)object { size_t length; | | | 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 | # endif @end @implementation OFRunLoopDatagramReceiveQueueItem - (bool)handleObject: (id)object { size_t length; OFSocketAddress address; id exception = nil; @try { length = [object receiveIntoBuffer: _buffer length: _length sender: &address]; } @catch (id e) { |
︙ | ︙ | |||
855 856 857 858 859 860 861 | receiver: &_receiver]; } @catch (id e) { exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { | | | 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 | receiver: &_receiver]; } @catch (id e) { exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { newData = _block(exception); if (newData == nil) return false; oldData = _data; _data = [newData copy]; [oldData release]; |
︙ | ︙ | |||
907 908 909 910 911 912 913 | @implementation OFRunLoopPacketReceiveQueueItem - (bool)handleObject: (id)object { size_t length; id exception = nil; @try { | | < | 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 | @implementation OFRunLoopPacketReceiveQueueItem - (bool)handleObject: (id)object { size_t length; id exception = nil; @try { length = [object receiveIntoBuffer: _buffer length: _length]; } @catch (id e) { length = 0; exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) |
︙ | ︙ | |||
957 958 959 960 961 962 963 | length: _data.count * _data.itemSize]; } @catch (id e) { exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { | | | 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 | length: _data.count * _data.itemSize]; } @catch (id e) { exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { newData = _block(exception); if (newData == nil) return false; oldData = _data; _data = [newData copy]; [oldData release]; |
︙ | ︙ | |||
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 | #endif } + (void)of_setMainRunLoop: (OFRunLoop *)runLoop { mainRunLoop = [runLoop retain]; } #ifdef OF_HAVE_SOCKETS # define NEW_READ(type, object, mode) \ void *pool = objc_autoreleasePoolPush(); \ OFRunLoop *runLoop = [self currentRunLoop]; \ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < | < | < | < | | | | | | | | | | | | | | | | | | | | | | | | < | < | 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 | #endif } + (void)of_setMainRunLoop: (OFRunLoop *)runLoop { mainRunLoop = [runLoop retain]; } static OFRunLoopState * stateForMode(OFRunLoop *self, OFRunLoopMode mode, bool create) { OFRunLoopState *state; #ifdef OF_HAVE_THREADS [self->_statesMutex lock]; @try { #endif state = [self->_states objectForKey: mode]; if (create && state == nil) { state = [[OFRunLoopState alloc] init]; @try { [self->_states setObject: state forKey: mode]; } @finally { [state release]; } } #ifdef OF_HAVE_THREADS } @finally { [self->_statesMutex unlock]; } #endif return state; } #ifdef OF_HAVE_SOCKETS # define NEW_READ(type, object, mode) \ void *pool = objc_autoreleasePoolPush(); \ OFRunLoop *runLoop = [self currentRunLoop]; \ OFRunLoopState *state = stateForMode(runLoop, mode, true); \ OFList *queue = [state->_readQueues objectForKey: object]; \ type *queueItem; \ \ if (queue == nil) { \ queue = [OFList list]; \ [state->_readQueues setObject: queue forKey: object]; \ } \ \ if (queue.count == 0) \ [state->_kernelEventObserver \ addObjectForReading: object]; \ \ queueItem = [[[type alloc] init] autorelease]; # define NEW_WRITE(type, object, mode) \ void *pool = objc_autoreleasePoolPush(); \ OFRunLoop *runLoop = [self currentRunLoop]; \ OFRunLoopState *state = stateForMode(runLoop, mode, true); \ OFList *queue = [state->_writeQueues objectForKey: object]; \ type *queueItem; \ \ if (queue == nil) { \ queue = [OFList list]; \ [state->_writeQueues setObject: queue forKey: object]; \ } \ \ if (queue.count == 0) \ [state->_kernelEventObserver \ addObjectForWriting: object]; \ \ queueItem = [[[type alloc] init] autorelease]; #define QUEUE_ITEM \ [queue appendObject: queueItem]; \ \ objc_autoreleasePoolPop(pool); + (void)of_addAsyncReadForStream: (OFStream <OFReadyForReadingObserving> *) stream buffer: (void *)buffer length: (size_t)length mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (OFStreamAsyncReadBlock)block # endif delegate: (id <OFStreamDelegate>)delegate { NEW_READ(OFRunLoopReadQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_buffer = buffer; queueItem->_length = length; QUEUE_ITEM } + (void)of_addAsyncReadForStream: (OFStream <OFReadyForReadingObserving> *) stream buffer: (void *)buffer exactLength: (size_t)exactLength mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (OFStreamAsyncReadBlock)block # endif delegate: (id <OFStreamDelegate>)delegate { NEW_READ(OFRunLoopExactReadQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_buffer = buffer; queueItem->_exactLength = exactLength; QUEUE_ITEM } + (void)of_addAsyncReadLineForStream: (OFStream <OFReadyForReadingObserving> *) stream encoding: (OFStringEncoding)encoding mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (OFStreamAsyncReadLineBlock)block # endif delegate: (id <OFStreamDelegate>)delegate { NEW_READ(OFRunLoopReadLineQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_encoding = encoding; QUEUE_ITEM } + (void)of_addAsyncWriteForStream: (OFStream <OFReadyForWritingObserving> *) stream data: (OFData *)data mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (OFStreamAsyncWriteDataBlock)block # endif delegate: (id <OFStreamDelegate>)delegate { NEW_WRITE(OFRunLoopWriteDataQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_data = [data copy]; QUEUE_ITEM } + (void)of_addAsyncWriteForStream: (OFStream <OFReadyForWritingObserving> *) stream string: (OFString *)string encoding: (OFStringEncoding)encoding mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (OFStreamAsyncWriteStringBlock)block # endif delegate: (id <OFStreamDelegate>)delegate { NEW_WRITE(OFRunLoopWriteStringQueueItem, stream, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_string = [string copy]; queueItem->_encoding = encoding; QUEUE_ITEM } # if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) + (void)of_addAsyncConnectForSocket: (id)sock mode: (OFRunLoopMode)mode delegate: (id <OFRunLoopConnectDelegate>)delegate { NEW_WRITE(OFRunLoopConnectQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; QUEUE_ITEM } # endif + (void)of_addAsyncAcceptForSocket: (id)sock mode: (OFRunLoopMode)mode block: (id)block delegate: (id)delegate { NEW_READ(OFRunLoopAcceptQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif QUEUE_ITEM } + (void)of_addAsyncReceiveForDatagramSocket: (OFDatagramSocket *)sock buffer: (void *)buffer length: (size_t)length mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (OFDatagramSocketAsyncReceiveBlock)block # endif delegate: (id <OFDatagramSocketDelegate>)delegate { NEW_READ(OFRunLoopDatagramReceiveQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_buffer = buffer; queueItem->_length = length; QUEUE_ITEM } + (void)of_addAsyncSendForDatagramSocket: (OFDatagramSocket *)sock data: (OFData *)data receiver: (const OFSocketAddress *)receiver mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (OFDatagramSocketAsyncSendDataBlock)block # endif delegate: (id <OFDatagramSocketDelegate>)delegate { NEW_WRITE(OFRunLoopDatagramSendQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_data = [data copy]; queueItem->_receiver = *receiver; QUEUE_ITEM } + (void)of_addAsyncReceiveForSequencedPacketSocket: (OFSequencedPacketSocket *) sock buffer: (void *)buffer length: (size_t)length mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (OFSequencedPacketSocketAsyncReceiveBlock)block # endif delegate: (id <OFSequencedPacketSocketDelegate>)delegate { NEW_READ(OFRunLoopPacketReceiveQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_buffer = buffer; queueItem->_length = length; QUEUE_ITEM } + (void)of_addAsyncSendForSequencedPacketSocket: (OFSequencedPacketSocket *)sock data: (OFData *)data mode: (OFRunLoopMode)mode # ifdef OF_HAVE_BLOCKS block: (OFSequencedPacketSocketAsyncSendDataBlock)block # endif delegate: (id <OFSequencedPacketSocketDelegate>)delegate { NEW_WRITE(OFRunLoopPacketSendQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_data = [data copy]; QUEUE_ITEM } # undef NEW_READ # undef NEW_WRITE # undef QUEUE_ITEM + (void)of_cancelAsyncRequestsForObject: (id)object mode: (OFRunLoopMode)mode { void *pool = objc_autoreleasePoolPush(); OFRunLoop *runLoop = [self currentRunLoop]; OFRunLoopState *state = stateForMode(runLoop, mode, false); OFList *queue; if (state == nil) return; if ((queue = [state->_writeQueues objectForKey: object]) != nil) { assert(queue.count > 0); |
︙ | ︙ | |||
1341 1342 1343 1344 1345 1346 1347 | @try { OFRunLoopState *state; _states = [[OFMutableDictionary alloc] init]; state = [[OFRunLoopState alloc] init]; @try { | | < | 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 | @try { OFRunLoopState *state; _states = [[OFMutableDictionary alloc] init]; state = [[OFRunLoopState alloc] init]; @try { [_states setObject: state forKey: OFDefaultRunLoopMode]; } @finally { [state release]; } #ifdef OF_HAVE_THREADS _statesMutex = [[OFMutex alloc] init]; #endif |
︙ | ︙ | |||
1368 1369 1370 1371 1372 1373 1374 | #ifdef OF_HAVE_THREADS [_statesMutex release]; #endif [super dealloc]; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | < | < | < | < | < > | > < < | | | | | < < | | | < | 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 | #ifdef OF_HAVE_THREADS [_statesMutex release]; #endif [super dealloc]; } - (void)addTimer: (OFTimer *)timer { [self addTimer: timer forMode: OFDefaultRunLoopMode]; } - (void)addTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode { OFRunLoopState *state = stateForMode(self, mode, true); #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif [state->_timersQueue insertObject: timer]; #ifdef OF_HAVE_THREADS } @finally { [state->_timersQueueMutex unlock]; } #endif [timer of_setInRunLoop: self mode: mode]; #if defined(OF_HAVE_SOCKETS) [state->_kernelEventObserver cancel]; #elif defined(OF_HAVE_THREADS) [state->_condition signal]; #endif } - (void)of_removeTimer: (OFTimer *)timer forMode: (OFRunLoopMode)mode { OFRunLoopState *state = stateForMode(self, mode, false); /* {} required to avoid -Wmisleading-indentation false positive. */ if (state == nil) { return; } #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif for (OFListItem iter = state->_timersQueue.firstListItem; iter != NULL; iter = OFListItemNext(iter)) { if ([OFListItemObject(iter) isEqual: timer]) { [state->_timersQueue removeListItem: iter]; break; } } #ifdef OF_HAVE_THREADS } @finally { [state->_timersQueueMutex unlock]; } #endif } #ifdef OF_AMIGAOS - (void)addExecSignal: (ULONG)signal target: (id)target selector: (SEL)selector { [self addExecSignal: signal forMode: OFDefaultRunLoopMode target: target selector: selector]; } - (void)addExecSignal: (ULONG)signal forMode: (OFRunLoopMode)mode target: (id)target selector: (SEL)selector { OFRunLoopState *state = stateForMode(self, mode, true); # ifdef OF_HAVE_THREADS [state->_execSignalsMutex lock]; @try { # endif [state->_execSignals addItem: &signal]; [state->_execSignalsTargets addObject: target]; |
︙ | ︙ | |||
1509 1510 1511 1512 1513 1514 1515 | } - (void)removeExecSignal: (ULONG)signal target: (id)target selector: (SEL)selector { [self removeExecSignal: signal | | | | < | 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 | } - (void)removeExecSignal: (ULONG)signal target: (id)target selector: (SEL)selector { [self removeExecSignal: signal forMode: OFDefaultRunLoopMode target: target selector: selector]; } - (void)removeExecSignal: (ULONG)signal forMode: (OFRunLoopMode)mode target: (id)target selector: (SEL)selector { OFRunLoopState *state = stateForMode(self, mode, false); if (state == nil) return; # ifdef OF_HAVE_THREADS [state->_execSignalsMutex lock]; @try { |
︙ | ︙ | |||
1580 1581 1582 1583 1584 1585 1586 | - (void)runUntilDate: (OFDate *)deadline { _stop = false; while (!_stop && (deadline == nil || deadline.timeIntervalSinceNow >= 0)) | < | < | | | < | | | > | | | | < | 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 | - (void)runUntilDate: (OFDate *)deadline { _stop = false; while (!_stop && (deadline == nil || deadline.timeIntervalSinceNow >= 0)) [self runMode: OFDefaultRunLoopMode beforeDate: deadline]; } - (void)runMode: (OFRunLoopMode)mode beforeDate: (OFDate *)deadline { void *pool = objc_autoreleasePoolPush(); OFRunLoopMode previousMode = _currentMode; OFRunLoopState *state = stateForMode(self, mode, false); if (state == nil) return; _currentMode = mode; @try { OFDate *nextTimer; #if defined(OF_AMIGAOS) && !defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS) ULONG signalMask; #endif for (;;) { OFTimer *timer; #ifdef OF_HAVE_THREADS [state->_timersQueueMutex lock]; @try { #endif OFListItem listItem = state->_timersQueue.firstListItem; if (listItem != NULL && [OFListItemObject(listItem) fireDate] .timeIntervalSinceNow <= 0) { timer = [[OFListItemObject(listItem) retain] autorelease]; [state->_timersQueue removeListItem: listItem]; [timer of_setInRunLoop: nil mode: nil]; } else break; #ifdef OF_HAVE_THREADS } @finally { [state->_timersQueueMutex unlock]; } #endif |
︙ | ︙ | |||
1650 1651 1652 1653 1654 1655 1656 | } @finally { [state->_timersQueueMutex unlock]; } #endif /* Watch for I/O events until the next timer is due */ if (nextTimer != nil || deadline != nil) { | | | 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 | } @finally { [state->_timersQueueMutex unlock]; } #endif /* Watch for I/O events until the next timer is due */ if (nextTimer != nil || deadline != nil) { OFTimeInterval timeout; if (nextTimer != nil && deadline == nil) timeout = nextTimer.timeIntervalSinceNow; else if (nextTimer == nil && deadline != nil) timeout = deadline.timeIntervalSinceNow; else timeout = [nextTimer earlierDate: deadline] |
︙ | ︙ | |||
1724 1725 1726 1727 1728 1729 1730 | } @finally { _currentMode = previousMode; } } - (void)stop { | | < | 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 | } @finally { _currentMode = previousMode; } } - (void)stop { OFRunLoopState *state = stateForMode(self, OFDefaultRunLoopMode, false); _stop = true; if (state == nil) return; #if defined(OF_HAVE_SOCKETS) [state->_kernelEventObserver cancel]; #elif defined(OF_HAVE_THREADS) [state->_condition signal]; #endif } @end |
Added src/OFRunLoopConstants.inc version [04d2ca961c].
> > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ const OFRunLoopMode OFDefaultRunLoopMode = @"OFDefaultRunLoopMode"; |
Deleted src/OFSCTPSocket.h version [5b42b1dc48].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFSCTPSocket.m version [f509519c08].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/OFSHA1Hash.h from [588a3c6fde] to [c7a73ceb16].
1 | /* | < < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFCryptographicHash.h" OF_ASSUME_NONNULL_BEGIN @class OFSecureData; /** * @class OFSHA1Hash OFSHA1Hash.h ObjFW/OFSHA1Hash.h * * @brief A class which provides methods to create an SHA-1 hash. */ OF_SUBCLASSING_RESTRICTED @interface OFSHA1Hash: OFObject <OFCryptographicHash> { OFSecureData *_iVarsData; struct { uint32_t state[5]; uint64_t bits; union { unsigned char bytes[64]; uint32_t words[80]; } buffer; size_t bufferLength; } *_iVars; bool _allowsSwappableMemory; bool _calculated; } @end OF_ASSUME_NONNULL_END |
Modified src/OFSHA1Hash.m from [cfb97974cb] to [6da836d4ff].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 | #include <string.h> #import "OFSHA1Hash.h" #import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFOutOfRangeException.h" | > < | > | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | #include <string.h> #import "OFSHA1Hash.h" #import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFHashNotCalculatedException.h" #import "OFOutOfRangeException.h" static const size_t digestSize = 20; static const size_t blockSize = 64; OF_DIRECT_MEMBERS @interface OFSHA1Hash () - (void)of_resetState; @end #define F(a, b, c, d) ((d) ^ ((b) & ((c) ^ (d)))) #define G(a, b, c, d) ((b) ^ (c) ^ (d)) #define H(a, b, c, d) (((b) & (c)) | ((d) & ((b) | (c)))) #define I(a, b, c, d) ((b) ^ (c) ^ (d)) static OF_INLINE void byteSwapVectorIfLE(uint32_t *vector, uint_fast8_t length) { #ifndef OF_BIG_ENDIAN for (uint_fast8_t i = 0; i < length; i++) vector[i] = OFByteSwap32(vector[i]); #endif } static void processBlock(uint32_t *state, uint32_t *buffer) { uint32_t new[5]; uint_fast8_t i; new[0] = state[0]; new[1] = state[1]; new[2] = state[2]; new[3] = state[3]; new[4] = state[4]; byteSwapVectorIfLE(buffer, 16); for (i = 16; i < 80; i++) { uint32_t tmp = buffer[i - 3] ^ buffer[i - 8] ^ buffer[i - 14] ^ buffer[i - 16]; buffer[i] = OFRotateLeft(tmp, 1); } #define LOOP_BODY(f, k) \ { \ uint32_t tmp = OFRotateLeft(new[0], 5) + \ f(new[0], new[1], new[2], new[3]) + \ new[4] + k + buffer[i]; \ new[4] = new[3]; \ new[3] = new[2]; \ new[2] = OFRotateLeft(new[1], 30); \ new[1] = new[0]; \ new[0] = tmp; \ } for (i = 0; i < 20; i++) LOOP_BODY(F, 0x5A827999) for (; i < 40; i++) |
︙ | ︙ | |||
99 100 101 102 103 104 105 | @implementation OFSHA1Hash @synthesize calculated = _calculated; @synthesize allowsSwappableMemory = _allowsSwappableMemory; + (size_t)digestSize { | | | | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | @implementation OFSHA1Hash @synthesize calculated = _calculated; @synthesize allowsSwappableMemory = _allowsSwappableMemory; + (size_t)digestSize { return digestSize; } + (size_t)blockSize { return blockSize; } + (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory { return [[[self alloc] initWithAllowsSwappableMemory: allowsSwappableMemory] autorelease]; } - (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory { |
︙ | ︙ | |||
152 153 154 155 156 157 158 | [_iVarsData release]; [super dealloc]; } - (size_t)digestSize { | | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | [_iVarsData release]; [super dealloc]; } - (size_t)digestSize { return digestSize; } - (size_t)blockSize { return blockSize; } - (id)copy { OFSHA1Hash *copy = [[OFSHA1Hash alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; |
︙ | ︙ | |||
181 182 183 184 185 186 187 | _iVars->state[0] = 0x67452301; _iVars->state[1] = 0xEFCDAB89; _iVars->state[2] = 0x98BADCFE; _iVars->state[3] = 0x10325476; _iVars->state[4] = 0xC3D2E1F0; } | | < | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | _iVars->state[0] = 0x67452301; _iVars->state[1] = 0xEFCDAB89; _iVars->state[2] = 0x98BADCFE; _iVars->state[3] = 0x10325476; _iVars->state[4] = 0xC3D2E1F0; } - (void)updateWithBuffer: (const void *)buffer_ length: (size_t)length { const unsigned char *buffer = buffer_; if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; |
︙ | ︙ | |||
217 218 219 220 221 222 223 | _iVars->bufferLength = 0; } } } - (const unsigned char *)digest { | | > > | | > > > > > > > | | | | | < < | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | _iVars->bufferLength = 0; } } } - (const unsigned char *)digest { if (!_calculated) @throw [OFHashNotCalculatedException exceptionWithObject: self]; return (const unsigned char *)_iVars->state; } - (void)calculate { if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; _iVars->buffer.bytes[_iVars->bufferLength] = 0x80; OFZeroMemory(_iVars->buffer.bytes + _iVars->bufferLength + 1, 64 - _iVars->bufferLength - 1); if (_iVars->bufferLength >= 56) { processBlock(_iVars->state, _iVars->buffer.words); OFZeroMemory(_iVars->buffer.bytes, 64); } _iVars->buffer.words[14] = OFToBigEndian32((uint32_t)(_iVars->bits >> 32)); _iVars->buffer.words[15] = OFToBigEndian32((uint32_t)(_iVars->bits & 0xFFFFFFFF)); processBlock(_iVars->state, _iVars->buffer.words); OFZeroMemory(&_iVars->buffer, sizeof(_iVars->buffer)); byteSwapVectorIfLE(_iVars->state, 5); _calculated = true; } - (void)reset { [self of_resetState]; _iVars->bits = 0; OFZeroMemory(&_iVars->buffer, sizeof(_iVars->buffer)); _iVars->bufferLength = 0; _calculated = false; } @end |
Modified src/OFSHA224Hash.h from [c733920226] to [ecc593c441].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFSHA224Hash.m from [cb55b029f3] to [5e5ae70827].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFSHA224Hash.h" static const size_t digestSize = 28; @implementation OFSHA224Hash + (size_t)digestSize { return digestSize; } - (size_t)digestSize { return digestSize; } - (void)of_resetState { _iVars->state[0] = 0xC1059ED8; _iVars->state[1] = 0x367CD507; _iVars->state[2] = 0x3070DD17; |
︙ | ︙ |
Modified src/OFSHA224Or256Hash.h from [0f791ad851] to [9235d0cf7a].
1 | /* | < < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFCryptographicHash.h" OF_ASSUME_NONNULL_BEGIN @class OFSecureData; /** * @class OFSHA224Or256Hash OFSHA224Or256Hash.h ObjFW/OFSHA224Or256Hash.h * * @brief A base class for SHA-224 and SHA-256. */ @interface OFSHA224Or256Hash: OFObject <OFCryptographicHash> { @private OFSecureData *_iVarsData; @protected struct { uint32_t state[8]; uint64_t bits; union { unsigned char bytes[64]; uint32_t words[64]; } buffer; size_t bufferLength; } *_iVars; @private bool _allowsSwappableMemory; bool _calculated; OF_RESERVE_IVARS(OFSHA224Or256Hash, 4) } @end OF_ASSUME_NONNULL_END |
Modified src/OFSHA224Or256Hash.m from [4e2317a38c] to [de7aa6c8f4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 | #include <stdlib.h> #include <string.h> #import "OFSHA224Or256Hash.h" #import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFOutOfRangeException.h" | > < > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <stdlib.h> #include <string.h> #import "OFSHA224Or256Hash.h" #import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFHashNotCalculatedException.h" #import "OFOutOfRangeException.h" static const size_t blockSize = 64; @interface OFSHA224Or256Hash () - (void)of_resetState; @end static const uint32_t table[] = { 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, |
︙ | ︙ | |||
52 53 54 55 56 57 58 | }; static OF_INLINE void byteSwapVectorIfLE(uint32_t *vector, uint_fast8_t length) { #ifndef OF_BIG_ENDIAN for (uint_fast8_t i = 0; i < length; i++) | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | }; static OF_INLINE void byteSwapVectorIfLE(uint32_t *vector, uint_fast8_t length) { #ifndef OF_BIG_ENDIAN for (uint_fast8_t i = 0; i < length; i++) vector[i] = OFByteSwap32(vector[i]); #endif } static void processBlock(uint32_t *state, uint32_t *buffer) { uint32_t new[8]; |
︙ | ︙ | |||
77 78 79 80 81 82 83 | byteSwapVectorIfLE(buffer, 16); for (i = 16; i < 64; i++) { uint32_t tmp; tmp = buffer[i - 2]; | | | | | | | | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | byteSwapVectorIfLE(buffer, 16); for (i = 16; i < 64; i++) { uint32_t tmp; tmp = buffer[i - 2]; buffer[i] = (OFRotateRight(tmp, 17) ^ OFRotateRight(tmp, 19) ^ (tmp >> 10)) + buffer[i - 7]; tmp = buffer[i - 15]; buffer[i] += (OFRotateRight(tmp, 7) ^ OFRotateRight(tmp, 18) ^ (tmp >> 3)) + buffer[i - 16]; } for (i = 0; i < 64; i++) { uint32_t tmp1 = new[7] + (OFRotateRight(new[4], 6) ^ OFRotateRight(new[4], 11) ^ OFRotateRight(new[4], 25)) + ((new[4] & (new[5] ^ new[6])) ^ new[6]) + table[i] + buffer[i]; uint32_t tmp2 = (OFRotateRight(new[0], 2) ^ OFRotateRight(new[0], 13) ^ OFRotateRight(new[0], 22)) + ((new[0] & (new[1] | new[2])) | (new[1] & new[2])); new[7] = new[6]; new[6] = new[5]; new[5] = new[4]; new[4] = new[3] + tmp1; new[3] = new[2]; |
︙ | ︙ | |||
124 125 126 127 128 129 130 | + (size_t)digestSize { OF_UNRECOGNIZED_SELECTOR } + (size_t)blockSize { | | | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | + (size_t)digestSize { OF_UNRECOGNIZED_SELECTOR } + (size_t)blockSize { return blockSize; } + (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory { return [[[self alloc] initWithAllowsSwappableMemory: allowsSwappableMemory] autorelease]; } - (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory { |
︙ | ︙ | |||
182 183 184 185 186 187 188 | - (size_t)digestSize { OF_UNRECOGNIZED_SELECTOR } - (size_t)blockSize { | | | < | 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | - (size_t)digestSize { OF_UNRECOGNIZED_SELECTOR } - (size_t)blockSize { return blockSize; } - (id)copy { OFSHA224Or256Hash *copy = [[[self class] alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; copy->_iVars = copy->_iVarsData.mutableItems; copy->_allowsSwappableMemory = _allowsSwappableMemory; copy->_calculated = _calculated; return copy; } - (void)updateWithBuffer: (const void *)buffer_ length: (size_t)length { const unsigned char *buffer = buffer_; if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; |
︙ | ︙ | |||
233 234 235 236 237 238 239 | _iVars->bufferLength = 0; } } } - (const unsigned char *)digest { | | > > | | > > > > > > > | | | | | < < | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | _iVars->bufferLength = 0; } } } - (const unsigned char *)digest { if (!_calculated) @throw [OFHashNotCalculatedException exceptionWithObject: self]; return (const unsigned char *)_iVars->state; } - (void)calculate { if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; _iVars->buffer.bytes[_iVars->bufferLength] = 0x80; OFZeroMemory(_iVars->buffer.bytes + _iVars->bufferLength + 1, 64 - _iVars->bufferLength - 1); if (_iVars->bufferLength >= 56) { processBlock(_iVars->state, _iVars->buffer.words); OFZeroMemory(_iVars->buffer.bytes, 64); } _iVars->buffer.words[14] = OFToBigEndian32((uint32_t)(_iVars->bits >> 32)); _iVars->buffer.words[15] = OFToBigEndian32((uint32_t)(_iVars->bits & 0xFFFFFFFF)); processBlock(_iVars->state, _iVars->buffer.words); OFZeroMemory(&_iVars->buffer, sizeof(_iVars->buffer)); byteSwapVectorIfLE(_iVars->state, 8); _calculated = true; } - (void)reset { [self of_resetState]; _iVars->bits = 0; OFZeroMemory(&_iVars->buffer, sizeof(_iVars->buffer)); _iVars->bufferLength = 0; _calculated = false; } - (void)of_resetState { OF_UNRECOGNIZED_SELECTOR } @end |
Modified src/OFSHA256Hash.h from [1c291a6b9d] to [29c7ad23a9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFSHA256Hash.m from [d6d4b0d05c] to [d082eb2586].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFSHA256Hash.h" static const size_t digestSize = 32; @implementation OFSHA256Hash + (size_t)digestSize { return digestSize; } - (size_t)digestSize { return digestSize; } - (void)of_resetState { _iVars->state[0] = 0x6A09E667; _iVars->state[1] = 0xBB67AE85; _iVars->state[2] = 0x3C6EF372; |
︙ | ︙ |
Modified src/OFSHA384Hash.h from [617b436074] to [7c87550526].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFSHA384Hash.m from [f950be9c9b] to [30d7ff4a68].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFSHA384Hash.h" static const size_t digestSize = 48; @implementation OFSHA384Hash + (size_t)digestSize { return digestSize; } - (size_t)digestSize { return digestSize; } - (void)of_resetState { _iVars->state[0] = 0xCBBB9D5DC1059ED8; _iVars->state[1] = 0x629A292A367CD507; _iVars->state[2] = 0x9159015A3070DD17; |
︙ | ︙ |
Modified src/OFSHA384Or512Hash.h from [2b8816dd44] to [889dffbb99].
1 | /* | < < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFCryptographicHash.h" OF_ASSUME_NONNULL_BEGIN @class OFSecureData; /** * @class OFSHA384Or512Hash OFSHA384Or512Hash.h ObjFW/OFSHA384Or512Hash.h * * @brief A base class for SHA-384 and SHA-512. */ @interface OFSHA384Or512Hash: OFObject <OFCryptographicHash> { @private OFSecureData *_iVarsData; @protected struct { uint64_t state[8]; uint64_t bits[2]; union { unsigned char bytes[128]; uint64_t words[80]; } buffer; size_t bufferLength; } *_iVars; @private bool _allowsSwappableMemory; bool _calculated; OF_RESERVE_IVARS(OFSHA384Or512Hash, 4) } @end OF_ASSUME_NONNULL_END |
Modified src/OFSHA384Or512Hash.m from [2e85a85b06] to [f0d2e79fad].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 | #include <stdlib.h> #include <string.h> #import "OFSHA384Or512Hash.h" #import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFOutOfRangeException.h" | > | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <stdlib.h> #include <string.h> #import "OFSHA384Or512Hash.h" #import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFHashNotCalculatedException.h" #import "OFOutOfRangeException.h" static const size_t blockSize = 128; @interface OFSHA384Or512Hash () - (void)of_resetState; @end static const uint64_t table[] = { 0x428A2F98D728AE22, 0x7137449123EF65CD, 0xB5C0FBCFEC4D3B2F, |
︙ | ︙ | |||
63 64 65 66 67 68 69 | }; static OF_INLINE void byteSwapVectorIfLE(uint64_t *vector, uint_fast8_t length) { #ifndef OF_BIG_ENDIAN for (uint_fast8_t i = 0; i < length; i++) | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | }; static OF_INLINE void byteSwapVectorIfLE(uint64_t *vector, uint_fast8_t length) { #ifndef OF_BIG_ENDIAN for (uint_fast8_t i = 0; i < length; i++) vector[i] = OFByteSwap64(vector[i]); #endif } static void processBlock(uint64_t *state, uint64_t *buffer) { uint64_t new[8]; |
︙ | ︙ | |||
88 89 90 91 92 93 94 | byteSwapVectorIfLE(buffer, 16); for (i = 16; i < 80; i++) { uint64_t tmp; tmp = buffer[i - 2]; | | | | | | | | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | byteSwapVectorIfLE(buffer, 16); for (i = 16; i < 80; i++) { uint64_t tmp; tmp = buffer[i - 2]; buffer[i] = (OFRotateRight(tmp, 19) ^ OFRotateRight(tmp, 61) ^ (tmp >> 6)) + buffer[i - 7]; tmp = buffer[i - 15]; buffer[i] += (OFRotateRight(tmp, 1) ^ OFRotateRight(tmp, 8) ^ (tmp >> 7)) + buffer[i - 16]; } for (i = 0; i < 80; i++) { uint64_t tmp1 = new[7] + (OFRotateRight(new[4], 14) ^ OFRotateRight(new[4], 18) ^ OFRotateRight(new[4], 41)) + ((new[4] & (new[5] ^ new[6])) ^ new[6]) + table[i] + buffer[i]; uint64_t tmp2 = (OFRotateRight(new[0], 28) ^ OFRotateRight(new[0], 34) ^ OFRotateRight(new[0], 39)) + ((new[0] & (new[1] | new[2])) | (new[1] & new[2])); new[7] = new[6]; new[6] = new[5]; new[5] = new[4]; new[4] = new[3] + tmp1; new[3] = new[2]; |
︙ | ︙ | |||
135 136 137 138 139 140 141 | + (size_t)digestSize { OF_UNRECOGNIZED_SELECTOR } + (size_t)blockSize { | | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | + (size_t)digestSize { OF_UNRECOGNIZED_SELECTOR } + (size_t)blockSize { return blockSize; } + (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory { return [[[self alloc] initWithAllowsSwappableMemory: allowsSwappableMemory] autorelease]; } - (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory { |
︙ | ︙ | |||
193 194 195 196 197 198 199 | - (size_t)digestSize { OF_UNRECOGNIZED_SELECTOR } - (size_t)blockSize { | | | < | 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | - (size_t)digestSize { OF_UNRECOGNIZED_SELECTOR } - (size_t)blockSize { return blockSize; } - (id)copy { OFSHA384Or512Hash *copy = [[[self class] alloc] of_init]; copy->_iVarsData = [_iVarsData copy]; copy->_iVars = copy->_iVarsData.mutableItems; copy->_allowsSwappableMemory = _allowsSwappableMemory; copy->_calculated = _calculated; return copy; } - (void)updateWithBuffer: (const void *)buffer_ length: (size_t)length { const unsigned char *buffer = buffer_; if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; |
︙ | ︙ | |||
246 247 248 249 250 251 252 | _iVars->bufferLength = 0; } } } - (const unsigned char *)digest { | | > > | | > > > > > > > | | | | | < < | | | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | _iVars->bufferLength = 0; } } } - (const unsigned char *)digest { if (!_calculated) @throw [OFHashNotCalculatedException exceptionWithObject: self]; return (const unsigned char *)_iVars->state; } - (void)calculate { if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; _iVars->buffer.bytes[_iVars->bufferLength] = 0x80; OFZeroMemory(_iVars->buffer.bytes + _iVars->bufferLength + 1, 128 - _iVars->bufferLength - 1); if (_iVars->bufferLength >= 112) { processBlock(_iVars->state, _iVars->buffer.words); OFZeroMemory(_iVars->buffer.bytes, 128); } _iVars->buffer.words[14] = OFToBigEndian64(_iVars->bits[1]); _iVars->buffer.words[15] = OFToBigEndian64(_iVars->bits[0]); processBlock(_iVars->state, _iVars->buffer.words); OFZeroMemory(&_iVars->buffer, sizeof(_iVars->buffer)); byteSwapVectorIfLE(_iVars->state, 8); _calculated = true; } - (void)reset { [self of_resetState]; OFZeroMemory(_iVars->bits, sizeof(_iVars->bits)); OFZeroMemory(&_iVars->buffer, sizeof(_iVars->buffer)); _iVars->bufferLength = 0; _calculated = false; } - (void)of_resetState { OF_UNRECOGNIZED_SELECTOR } @end |
Modified src/OFSHA512Hash.h from [8253dbc793] to [b25fc86287].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFSHA512Hash.m from [96269c9e3c] to [b08066342d].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFSHA512Hash.h" static const size_t digestSize = 64; @implementation OFSHA512Hash + (size_t)digestSize { return digestSize; } - (size_t)digestSize { return digestSize; } - (void)of_resetState { _iVars->state[0] = 0x6A09E667F3BCC908; _iVars->state[1] = 0xBB67AE8584CAA73B; _iVars->state[2] = 0x3C6EF372FE94F82B; |
︙ | ︙ |
Modified src/OFSPXSocket.h from [66a0b3680e] to [0544ae262f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | #ifdef OF_HAVE_BLOCKS /** * @brief A block which is called when the socket connected. * * @param exception An exception which occurred while connecting the socket or * `nil` on success */ | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #ifdef OF_HAVE_BLOCKS /** * @brief A block which is called when the socket connected. * * @param exception An exception which occurred while connecting the socket or * `nil` on success */ typedef void (^OFSPXSocketAsyncConnectBlock)(id _Nullable exception); #endif /** * @protocol OFSPXSocketDelegate OFSPXSocket.h ObjFW/OFSPXSocket.h * * A delegate for OFSPXSocket. */ |
︙ | ︙ | |||
116 117 118 119 120 121 122 | * @param port The port (sometimes also called socket number) on the node to * connect to * @param runLoopMode The run loop mode in which to perform the async connect */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port | | | | | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | * @param port The port (sometimes also called socket number) on the node to * connect to * @param runLoopMode The run loop mode in which to perform the async connect */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode; #ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously connect the OFSPXSocket to the specified destination. * * @param node The node to connect to * @param network The network on which the node to connect to is * @param port The port (sometimes also called socket number) on the node to * connect to * @param block The block to execute once the connection has been established */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port block: (OFSPXSocketAsyncConnectBlock)block; /** * @brief Asynchronously connect the OFSPXSocket to the specified destination. * * @param node The node to connect to * @param network The network on which the node to connect to is * @param port The port (sometimes also called socket number) on the node to * connect to * @param runLoopMode The run loop mode in which to perform the async connect * @param block The block to execute once the connection has been established */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode block: (OFSPXSocketAsyncConnectBlock)block; #endif /** * @brief Bind the socket to the specified network, node and port. * * @param port The port (sometimes called socket number) to bind to. 0 means to * pick one and return it. * @return The address on which this socket can be reached */ - (OFSocketAddress)bindToPort: (uint16_t)port; @end OF_ASSUME_NONNULL_END |
Modified src/OFSPXSocket.m from [c3e334ddfc] to [772214332c].
1 | /* | < < | > > < < < | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFSPXSocket.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" #import "OFConnectionFailedException.h" #import "OFNotOpenException.h" #ifndef NSPROTO_SPX # define NSPROTO_SPX 0 #endif static const uint8_t SPXPacketType = 5; @interface OFSPXSocket () - (int)of_createSocketForAddress: (const OFSocketAddress *)address errNo: (int *)errNo; - (bool)of_connectSocketToAddress: (const OFSocketAddress *)address errNo: (int *)errNo; - (void)of_closeSocket; @end OF_DIRECT_MEMBERS @interface OFSPXSocketAsyncConnectDelegate: OFObject <OFRunLoopConnectDelegate> { OFSPXSocket *_socket; unsigned char _node[IPX_NODE_LEN]; uint32_t _network; uint16_t _port; #ifdef OF_HAVE_BLOCKS OFSPXSocketAsyncConnectBlock _block; #endif } - (instancetype)initWithSocket: (OFSPXSocket *)socket node: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port #ifdef OF_HAVE_BLOCKS block: (OFSPXSocketAsyncConnectBlock)block #endif ; - (void)startWithRunLoopMode: (OFRunLoopMode)runLoopMode; @end @implementation OFSPXSocketAsyncConnectDelegate - (instancetype)initWithSocket: (OFSPXSocket *)sock node: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port #ifdef OF_HAVE_BLOCKS block: (OFSPXSocketAsyncConnectBlock)block #endif { self = [super init]; @try { _socket = [sock retain]; memcpy(_node, node, IPX_NODE_LEN); |
︙ | ︙ | |||
101 102 103 104 105 106 107 | #ifdef OF_HAVE_BLOCKS [_block release]; #endif [super dealloc]; } | | | | | < | > | > > | < | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | #ifdef OF_HAVE_BLOCKS [_block release]; #endif [super dealloc]; } - (void)startWithRunLoopMode: (OFRunLoopMode)runLoopMode { OFSocketAddress address = OFSocketAddressMakeIPX(_node, _network, _port); id exception = nil; int errNo; if (![_socket of_createSocketForAddress: &address errNo: &errNo]) { exception = [self of_connectionFailedExceptionForErrNo: errNo]; goto inform_delegate; } _socket.canBlock = false; if (![_socket of_connectSocketToAddress: &address errNo: &errNo]) { #ifdef OF_WINDOWS if (errNo == EINPROGRESS || errNo == EWOULDBLOCK) { #else if (errNo == EINPROGRESS) { #endif [OFRunLoop of_addAsyncConnectForSocket: _socket mode: runLoopMode delegate: self]; return; } [_socket of_closeSocket]; exception = [self of_connectionFailedExceptionForErrNo: errNo]; } inform_delegate: [self performSelector: @selector(of_socketDidConnect:exception:) withObject: _socket withObject: exception afterDelay: 0]; } - (void)of_socketDidConnect: (id)sock exception: (id)exception { id <OFSPXSocketDelegate> delegate = ((OFSPXSocket *)sock).delegate; if (exception == nil) ((OFSPXSocket *)sock).canBlock = true; #ifdef OF_HAVE_BLOCKS |
︙ | ︙ | |||
175 176 177 178 179 180 181 | errNo: errNo]; } @end @implementation OFSPXSocket @dynamic delegate; | | | | > | | | | | < | | < | < | | | | | | | | | | | > | | | | | | | | | | | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | errNo: errNo]; } @end @implementation OFSPXSocket @dynamic delegate; - (int)of_createSocketForAddress: (const OFSocketAddress *)address errNo: (int *)errNo { #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if ((_socket = socket(address->sockaddr.ipx.sipx_family, SOCK_SEQPACKET | SOCK_CLOEXEC, NSPROTO_SPX)) == OFInvalidSocketHandle) { *errNo = OFSocketErrNo(); return false; } #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif return true; } - (bool)of_connectSocketToAddress: (const OFSocketAddress *)address errNo: (int *)errNo { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; if (connect(_socket, &address->sockaddr.sockaddr, address->length) != 0) { *errNo = OFSocketErrNo(); return false; } return true; } - (void)of_closeSocket { closesocket(_socket); _socket = OFInvalidSocketHandle; } - (void)connectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port { OFSocketAddress address = OFSocketAddressMakeIPX(node, network, port); int errNo; if (![self of_createSocketForAddress: &address errNo: &errNo]) @throw [OFConnectionFailedException exceptionWithNode: node network: network port: port socket: self errNo: errNo]; if (![self of_connectSocketToAddress: &address errNo: &errNo]) { [self of_closeSocket]; @throw [OFConnectionFailedException exceptionWithNode: node network: network port: port socket: self errNo: errNo]; } } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port { [self asyncConnectToNode: node network: network port: port runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode { void *pool = objc_autoreleasePoolPush(); [[[[OFSPXSocketAsyncConnectDelegate alloc] initWithSocket: self node: node network: network port: port #ifdef OF_HAVE_BLOCKS block: NULL #endif ] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port block: (OFSPXSocketAsyncConnectBlock)block { [self asyncConnectToNode: node network: network port: port runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode block: (OFSPXSocketAsyncConnectBlock)block { void *pool = objc_autoreleasePoolPush(); [[[[OFSPXSocketAsyncConnectDelegate alloc] initWithSocket: self node: node network: network port: port block: block ] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #endif - (OFSocketAddress)bindToPort: (uint16_t)port { const unsigned char zeroNode[IPX_NODE_LEN] = { 0 }; OFSocketAddress address; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; address = OFSocketAddressMakeIPX(zeroNode, 0, port); if ((_socket = socket(address.sockaddr.sockaddr.sa_family, SOCK_SEQPACKET | SOCK_CLOEXEC, NSPROTO_SPX)) == OFInvalidSocketHandle) @throw [OFBindFailedException exceptionWithPort: port packetType: SPXPacketType socket: self errNo: OFSocketErrNo()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithPort: port packetType: SPXPacketType socket: self errNo: errNo]; } memset(&address, 0, sizeof(address)); address.family = OFSocketAddressFamilyIPX; address.length = (socklen_t)sizeof(address.sockaddr); if (OFGetSockName(_socket, &address.sockaddr.sockaddr, &address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithPort: port packetType: SPXPacketType socket: self errNo: errNo]; } if (address.sockaddr.sockaddr.sa_family != AF_IPX) { closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithPort: port packetType: SPXPacketType socket: self errNo: EAFNOSUPPORT]; } return address; } @end |
Modified src/OFSPXStreamSocket.h from [809200c97d] to [ccec1c33a6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | #ifdef OF_HAVE_BLOCKS /** * @brief A block which is called when the socket connected. * * @param exception An exception which occurred while connecting the socket or * `nil` on success */ | < | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #ifdef OF_HAVE_BLOCKS /** * @brief A block which is called when the socket connected. * * @param exception An exception which occurred while connecting the socket or * `nil` on success */ typedef void (^OFSPXStreamSocketAsyncConnectBlock)(id _Nullable exception); #endif /** * @protocol OFSPXStreamSocketDelegate OFSPXStreamSocket.h \ * ObjFW/OFSPXStreamSocket.h * * A delegate for OFSPXStreamSocket. |
︙ | ︙ | |||
120 121 122 123 124 125 126 | * @param port The port (sometimes also called socket number) on the node to * connect to * @param runLoopMode The run loop mode in which to perform the async connect */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port | | | | | | | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | * @param port The port (sometimes also called socket number) on the node to * connect to * @param runLoopMode The run loop mode in which to perform the async connect */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode; #ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously connect the OFSPXStreamSocket to the specified * destination. * * @param node The node to connect to * @param network The network on which the node to connect to is * @param port The port (sometimes also called socket number) on the node to * connect to * @param block The block to execute once the connection has been established */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port block: (OFSPXStreamSocketAsyncConnectBlock)block; /** * @brief Asynchronously connect the OFSPXStreamSocket to the specified * destination. * * @param node The node to connect to * @param network The network on which the node to connect to is * @param port The port (sometimes also called socket number) on the node to * connect to * @param runLoopMode The run loop mode in which to perform the async connect * @param block The block to execute once the connection has been established */ - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode block: (OFSPXStreamSocketAsyncConnectBlock)block; #endif /** * @brief Bind the socket to the specified network, node and port. * * @param port The port (sometimes called socket number) to bind to. 0 means to * pick one and return it. * @return The address on which this socket can be reached */ - (OFSocketAddress)bindToPort: (uint16_t)port; @end OF_ASSUME_NONNULL_END |
Modified src/OFSPXStreamSocket.m from [fcd6269f1f] to [f7ce692f2d].
1 | /* | < < | > > < < < | | | | < | | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFSPXStreamSocket.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" #import "OFConnectionFailedException.h" #import "OFNotOpenException.h" #ifndef NSPROTO_SPX # define NSPROTO_SPX 0 #endif static const uint8_t SPXPacketType = 5; @interface OFSPXStreamSocket () - (int)of_createSocketForAddress: (const OFSocketAddress *)address errNo: (int *)errNo; - (bool)of_connectSocketToAddress: (const OFSocketAddress *)address errNo: (int *)errNo; - (void)of_closeSocket; @end OF_DIRECT_MEMBERS @interface OFSPXStreamSocketAsyncConnectDelegate: OFObject <OFRunLoopConnectDelegate> { OFSPXStreamSocket *_socket; unsigned char _node[IPX_NODE_LEN]; uint32_t _network; uint16_t _port; #ifdef OF_HAVE_BLOCKS OFSPXStreamSocketAsyncConnectBlock _block; #endif } - (instancetype)initWithSocket: (OFSPXStreamSocket *)socket node: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port #ifdef OF_HAVE_BLOCKS block: (OFSPXStreamSocketAsyncConnectBlock)block #endif ; - (void)startWithRunLoopMode: (OFRunLoopMode)runLoopMode; @end @implementation OFSPXStreamSocketAsyncConnectDelegate - (instancetype)initWithSocket: (OFSPXStreamSocket *)sock node: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port #ifdef OF_HAVE_BLOCKS block: (OFSPXStreamSocketAsyncConnectBlock)block #endif { self = [super init]; @try { _socket = [sock retain]; memcpy(_node, node, IPX_NODE_LEN); |
︙ | ︙ | |||
104 105 106 107 108 109 110 | #ifdef OF_HAVE_BLOCKS [_block release]; #endif [super dealloc]; } | | | | | < | > | > > | < | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | #ifdef OF_HAVE_BLOCKS [_block release]; #endif [super dealloc]; } - (void)startWithRunLoopMode: (OFRunLoopMode)runLoopMode { OFSocketAddress address = OFSocketAddressMakeIPX(_node, _network, _port); id exception = nil; int errNo; if (![_socket of_createSocketForAddress: &address errNo: &errNo]) { exception = [self of_connectionFailedExceptionForErrNo: errNo]; goto inform_delegate; } _socket.canBlock = false; if (![_socket of_connectSocketToAddress: &address errNo: &errNo]) { #ifdef OF_WINDOWS if (errNo == EINPROGRESS || errNo == EWOULDBLOCK) { #else if (errNo == EINPROGRESS) { #endif [OFRunLoop of_addAsyncConnectForSocket: _socket mode: runLoopMode delegate: self]; return; } [_socket of_closeSocket]; exception = [self of_connectionFailedExceptionForErrNo: errNo]; } inform_delegate: [self performSelector: @selector(of_socketDidConnect:exception:) withObject: _socket withObject: exception afterDelay: 0]; } - (void)of_socketDidConnect: (id)sock exception: (id)exception { id <OFSPXStreamSocketDelegate> delegate = ((OFSPXStreamSocket *)sock).delegate; if (exception == nil) ((OFSPXStreamSocket *)sock).canBlock = true; |
︙ | ︙ | |||
179 180 181 182 183 184 185 | errNo: errNo]; } @end @implementation OFSPXStreamSocket @dynamic delegate; | | | | > | | | | | < | | < | < | | | | | | | | | | | | | | | | | | | | | | | | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | errNo: errNo]; } @end @implementation OFSPXStreamSocket @dynamic delegate; - (int)of_createSocketForAddress: (const OFSocketAddress *)address errNo: (int *)errNo { #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if ((_socket = socket(address->sockaddr.ipx.sipx_family, SOCK_SEQPACKET | SOCK_CLOEXEC, NSPROTO_SPX)) == OFInvalidSocketHandle) { *errNo = OFSocketErrNo(); return false; } #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif return true; } - (bool)of_connectSocketToAddress: (const OFSocketAddress *)address errNo: (int *)errNo { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; if (connect(_socket, &address->sockaddr.sockaddr, address->length) != 0) { *errNo = OFSocketErrNo(); return false; } return true; } - (void)of_closeSocket { closesocket(_socket); _socket = OFInvalidSocketHandle; } - (void)connectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port { OFSocketAddress address = OFSocketAddressMakeIPX(node, network, port); int errNo; if (![self of_createSocketForAddress: &address errNo: &errNo]) @throw [OFConnectionFailedException exceptionWithNode: node network: network port: port socket: self errNo: errNo]; if (![self of_connectSocketToAddress: &address errNo: &errNo]) { [self of_closeSocket]; @throw [OFConnectionFailedException exceptionWithNode: node network: network port: port socket: self errNo: errNo]; } } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port { [self asyncConnectToNode: node network: network port: port runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode { void *pool = objc_autoreleasePoolPush(); [[[[OFSPXStreamSocketAsyncConnectDelegate alloc] initWithSocket: self node: node network: network port: port #ifdef OF_HAVE_BLOCKS block: NULL #endif ] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port block: (OFSPXStreamSocketAsyncConnectBlock)block { [self asyncConnectToNode: node network: network port: port runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncConnectToNode: (unsigned char [_Nonnull IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode block: (OFSPXStreamSocketAsyncConnectBlock)block { void *pool = objc_autoreleasePoolPush(); [[[[OFSPXStreamSocketAsyncConnectDelegate alloc] initWithSocket: self node: node network: network port: port block: block ] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #endif - (OFSocketAddress)bindToPort: (uint16_t)port { const unsigned char zeroNode[IPX_NODE_LEN] = { 0 }; OFSocketAddress address; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; address = OFSocketAddressMakeIPX(zeroNode, 0, port); if ((_socket = socket(address.sockaddr.sockaddr.sa_family, SOCK_STREAM | SOCK_CLOEXEC, NSPROTO_SPX)) == OFInvalidSocketHandle) @throw [OFBindFailedException exceptionWithPort: port packetType: SPXPacketType socket: self errNo: OFSocketErrNo()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithPort: port packetType: SPXPacketType socket: self errNo: errNo]; } memset(&address, 0, sizeof(address)); address.family = OFSocketAddressFamilyIPX; address.length = (socklen_t)sizeof(address.sockaddr); if (OFGetSockName(_socket, &address.sockaddr.sockaddr, &address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithPort: port packetType: SPXPacketType socket: self errNo: errNo]; } if (address.sockaddr.sockaddr.sa_family != AF_IPX) { closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithPort: port packetType: SPXPacketType socket: self errNo: EAFNOSUPPORT]; } return address; } @end |
Modified src/OFSandbox.h from [e483b091af] to [8f1c6b186c].
1 | /* | < < | < < < < < < | < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFPair OF_GENERIC(FirstType, SecondType); typedef OFPair OF_GENERIC(OFString *, OFString *) *OFSandboxUnveilPath; @interface OFSandbox: OFObject <OFCopying> { unsigned int _allowsStdIO: 1; unsigned int _allowsReadingFiles: 1; unsigned int _allowsWritingFiles: 1; unsigned int _allowsCreatingFiles: 1; unsigned int _allowsCreatingSpecialFiles: 1; |
︙ | ︙ | |||
64 65 66 67 68 69 70 | unsigned int _allowsVMInfo: 1; unsigned int _allowsChangingProcessRights: 1; unsigned int _allowsPF: 1; unsigned int _allowsAudio: 1; unsigned int _allowsBPF: 1; unsigned int _allowsUnveil: 1; unsigned int _returnsErrors: 1; | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < | < | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | unsigned int _allowsVMInfo: 1; unsigned int _allowsChangingProcessRights: 1; unsigned int _allowsPF: 1; unsigned int _allowsAudio: 1; unsigned int _allowsBPF: 1; unsigned int _allowsUnveil: 1; unsigned int _returnsErrors: 1; OFMutableArray OF_GENERIC(OFSandboxUnveilPath) *_unveiledPaths; @public size_t _unveiledPathsIndex; OF_RESERVE_IVARS(OFSandbox, 4) } @property (nonatomic) bool allowsStdIO; @property (nonatomic) bool allowsReadingFiles; @property (nonatomic) bool allowsWritingFiles; @property (nonatomic) bool allowsCreatingFiles; @property (nonatomic) bool allowsCreatingSpecialFiles; @property (nonatomic) bool allowsTemporaryFiles; @property (nonatomic) bool allowsIPSockets; @property (nonatomic) bool allowsMulticastSockets; @property (nonatomic) bool allowsChangingFileAttributes; @property (nonatomic) bool allowsFileOwnerChanges; @property (nonatomic) bool allowsFileLocks; @property (nonatomic) bool allowsUNIXSockets; @property (nonatomic) bool allowsDNS; @property (nonatomic) bool allowsUserDatabaseReading; @property (nonatomic) bool allowsFileDescriptorSending; @property (nonatomic) bool allowsFileDescriptorReceiving; @property (nonatomic) bool allowsTape; @property (nonatomic) bool allowsTTY; @property (nonatomic) bool allowsProcessOperations; @property (nonatomic) bool allowsExec; @property (nonatomic) bool allowsProtExec; @property (nonatomic) bool allowsSetTime; @property (nonatomic) bool allowsPS; @property (nonatomic) bool allowsVMInfo; @property (nonatomic) bool allowsChangingProcessRights; @property (nonatomic) bool allowsPF; @property (nonatomic) bool allowsAudio; @property (nonatomic) bool allowsBPF; @property (nonatomic) bool allowsUnveil; @property (nonatomic) bool returnsErrors; #ifdef OF_HAVE_PLEDGE @property (readonly, nonatomic) OFString *pledgeString; #endif @property (readonly, nonatomic) OFArray OF_GENERIC(OFSandboxUnveilPath) *unveiledPaths; + (instancetype)sandbox; - (void)unveilPath: (OFString *)path permissions: (OFString *)permissions; @end OF_ASSUME_NONNULL_END |
Modified src/OFSandbox.m from [103c5612bc] to [a04c417381].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
467 468 469 470 471 472 473 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAdd(&hash, _allowsStdIO); OFHashAdd(&hash, _allowsReadingFiles); OFHashAdd(&hash, _allowsWritingFiles); OFHashAdd(&hash, _allowsCreatingFiles); OFHashAdd(&hash, _allowsCreatingSpecialFiles); OFHashAdd(&hash, _allowsTemporaryFiles); OFHashAdd(&hash, _allowsIPSockets); OFHashAdd(&hash, _allowsMulticastSockets); OFHashAdd(&hash, _allowsChangingFileAttributes); OFHashAdd(&hash, _allowsFileOwnerChanges); OFHashAdd(&hash, _allowsFileLocks); OFHashAdd(&hash, _allowsUNIXSockets); OFHashAdd(&hash, _allowsDNS); OFHashAdd(&hash, _allowsUserDatabaseReading); OFHashAdd(&hash, _allowsFileDescriptorSending); OFHashAdd(&hash, _allowsFileDescriptorReceiving); OFHashAdd(&hash, _allowsTape); OFHashAdd(&hash, _allowsTTY); OFHashAdd(&hash, _allowsProcessOperations); OFHashAdd(&hash, _allowsExec); OFHashAdd(&hash, _allowsProtExec); OFHashAdd(&hash, _allowsSetTime); OFHashAdd(&hash, _allowsPS); OFHashAdd(&hash, _allowsVMInfo); OFHashAdd(&hash, _allowsChangingProcessRights); OFHashAdd(&hash, _allowsPF); OFHashAdd(&hash, _allowsAudio); OFHashAdd(&hash, _allowsBPF); OFHashAdd(&hash, _allowsUnveil); OFHashAdd(&hash, _returnsErrors); OFHashFinalize(&hash); return hash; } #ifdef OF_HAVE_PLEDGE - (OFString *)pledgeString { |
︙ | ︙ | |||
585 586 587 588 589 590 591 | objc_autoreleasePoolPop(pool); return [ret autorelease]; } #endif | | < | | 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 | objc_autoreleasePoolPop(pool); return [ret autorelease]; } #endif - (void)unveilPath: (OFString *)path permissions: (OFString *)permissions { void *pool = objc_autoreleasePoolPush(); [_unveiledPaths addObject: [OFPair pairWithFirstObject: path secondObject: permissions]]; objc_autoreleasePoolPop(pool); } - (OFArray OF_GENERIC(OFSandboxUnveilPath) *)unveiledPaths { return [[_unveiledPaths copy] autorelease]; } @end |
Renamed and modified src/scrypt.h [75597e6dd2] to src/OFScrypt.h [7e18036f48].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFHMAC; /** | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFHMAC; /** * @brief The parameters for @ref OFScrypt. */ typedef struct { /** @brief The block size to use. */ size_t blockSize; /** @brief The CPU/memory cost factor to use. */ size_t costFactor; /** @brief The parallelization to use. */ size_t parallelization; /** @brief The salt to derive a key with. */ |
︙ | ︙ | |||
54 55 56 57 58 59 60 | * @brief The desired length for the derived key. * * @ref key needs to have enough storage. */ size_t keyLength; /** @brief Whether data may be stored in swappable memory. */ bool allowsSwappableMemory; | | | | | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | * @brief The desired length for the derived key. * * @ref key needs to have enough storage. */ size_t keyLength; /** @brief Whether data may be stored in swappable memory. */ bool allowsSwappableMemory; } OFScryptParameters; #ifdef __cplusplus extern "C" { #endif extern void OFSalsa20_8Core(uint32_t buffer[_Nonnull 16]); extern void OFScryptBlockMix(uint32_t *output, const uint32_t *input, size_t blockSize); extern void OFScryptROMix(uint32_t *buffer, size_t blockSize, size_t costFactor, uint32_t *tmp); /** * @brief Derives a key from a password and a salt using scrypt. * * @param param The parameters to use */ extern void OFScrypt(OFScryptParameters param); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Renamed and modified src/scrypt.m [163ddcc8f1] to src/OFScrypt.m [730aa203eb].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | #import "OFSHA256Hash.h" #import "OFSecureData.h" #import "OFInvalidArgumentException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | #import "OFSHA256Hash.h" #import "OFSecureData.h" #import "OFInvalidArgumentException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFScrypt.h" #import "OFPBKDF2.h" void OFSalsa20_8Core(uint32_t buffer[16]) { uint32_t tmp[16]; for (uint_fast8_t i = 0; i < 16; i++) tmp[i] = OFToLittleEndian32(buffer[i]); for (uint_fast8_t i = 0; i < 8; i += 2) { tmp[ 4] ^= OFRotateLeft(tmp[ 0] + tmp[12], 7); tmp[ 8] ^= OFRotateLeft(tmp[ 4] + tmp[ 0], 9); tmp[12] ^= OFRotateLeft(tmp[ 8] + tmp[ 4], 13); tmp[ 0] ^= OFRotateLeft(tmp[12] + tmp[ 8], 18); tmp[ 9] ^= OFRotateLeft(tmp[ 5] + tmp[ 1], 7); tmp[13] ^= OFRotateLeft(tmp[ 9] + tmp[ 5], 9); tmp[ 1] ^= OFRotateLeft(tmp[13] + tmp[ 9], 13); tmp[ 5] ^= OFRotateLeft(tmp[ 1] + tmp[13], 18); tmp[14] ^= OFRotateLeft(tmp[10] + tmp[ 6], 7); tmp[ 2] ^= OFRotateLeft(tmp[14] + tmp[10], 9); tmp[ 6] ^= OFRotateLeft(tmp[ 2] + tmp[14], 13); tmp[10] ^= OFRotateLeft(tmp[ 6] + tmp[ 2], 18); tmp[ 3] ^= OFRotateLeft(tmp[15] + tmp[11], 7); tmp[ 7] ^= OFRotateLeft(tmp[ 3] + tmp[15], 9); tmp[11] ^= OFRotateLeft(tmp[ 7] + tmp[ 3], 13); tmp[15] ^= OFRotateLeft(tmp[11] + tmp[ 7], 18); tmp[ 1] ^= OFRotateLeft(tmp[ 0] + tmp[ 3], 7); tmp[ 2] ^= OFRotateLeft(tmp[ 1] + tmp[ 0], 9); tmp[ 3] ^= OFRotateLeft(tmp[ 2] + tmp[ 1], 13); tmp[ 0] ^= OFRotateLeft(tmp[ 3] + tmp[ 2], 18); tmp[ 6] ^= OFRotateLeft(tmp[ 5] + tmp[ 4], 7); tmp[ 7] ^= OFRotateLeft(tmp[ 6] + tmp[ 5], 9); tmp[ 4] ^= OFRotateLeft(tmp[ 7] + tmp[ 6], 13); tmp[ 5] ^= OFRotateLeft(tmp[ 4] + tmp[ 7], 18); tmp[11] ^= OFRotateLeft(tmp[10] + tmp[ 9], 7); tmp[ 8] ^= OFRotateLeft(tmp[11] + tmp[10], 9); tmp[ 9] ^= OFRotateLeft(tmp[ 8] + tmp[11], 13); tmp[10] ^= OFRotateLeft(tmp[ 9] + tmp[ 8], 18); tmp[12] ^= OFRotateLeft(tmp[15] + tmp[14], 7); tmp[13] ^= OFRotateLeft(tmp[12] + tmp[15], 9); tmp[14] ^= OFRotateLeft(tmp[13] + tmp[12], 13); tmp[15] ^= OFRotateLeft(tmp[14] + tmp[13], 18); } for (uint_fast8_t i = 0; i < 16; i++) buffer[i] = OFToLittleEndian32(OFFromLittleEndian32(buffer[i]) + tmp[i]); OFZeroMemory(tmp, sizeof(tmp)); } void OFScryptBlockMix(uint32_t *output, const uint32_t *input, size_t blockSize) { uint32_t tmp[16]; /* Check defined here and executed in OFScrypt() */ #define OVERFLOW_CHECK_1 \ if (param.blockSize > SIZE_MAX / 2 || \ 2 * param.blockSize - 1 > SIZE_MAX / 16) \ @throw [OFOutOfRangeException exception]; memcpy(tmp, input + (2 * blockSize - 1) * 16, 64); for (size_t i = 0; i < 2 * blockSize; i++) { for (size_t j = 0; j < 16; j++) tmp[j] ^= input[i * 16 + j]; OFSalsa20_8Core(tmp); /* * Even indices are stored in the first half and odd ones in * the second. */ memcpy(output + ((i / 2) + (i & 1) * blockSize) * 16, tmp, 64); } OFZeroMemory(tmp, sizeof(tmp)); } void OFScryptROMix(uint32_t *buffer, size_t blockSize, size_t costFactor, uint32_t *tmp) { /* Check defined here and executed in OFScrypt() */ #define OVERFLOW_CHECK_2 \ if (param.blockSize > SIZE_MAX / 128 / param.costFactor) \ @throw [OFOutOfRangeException exception]; uint32_t *tmp2 = tmp + 32 * blockSize; memcpy(tmp, buffer, 128 * blockSize); for (size_t i = 0; i < costFactor; i++) { memcpy(tmp2 + i * 32 * blockSize, tmp, 128 * blockSize); OFScryptBlockMix(tmp, tmp2 + i * 32 * blockSize, blockSize); } for (size_t i = 0; i < costFactor; i++) { uint32_t j = OFFromLittleEndian32( tmp[(2 * blockSize - 1) * 16]) & (costFactor - 1); for (size_t k = 0; k < 32 * blockSize; k++) tmp[k] ^= tmp2[j * 32 * blockSize + k]; OFScryptBlockMix(buffer, tmp, blockSize); if (i < costFactor - 1) memcpy(tmp, buffer, 128 * blockSize); } } void OFScrypt(OFScryptParameters param) { OFSecureData *tmp = nil, *buffer = nil; OFHMAC *HMAC = nil; if (param.blockSize == 0 || param.costFactor <= 1 || (param.costFactor & (param.costFactor - 1)) != 0 || param.parallelization == 0) |
︙ | ︙ | |||
162 163 164 165 166 167 168 | uint32_t *tmpItems, *bufferItems; if (param.costFactor > SIZE_MAX - 1 || (param.costFactor + 1) > SIZE_MAX / 128) @throw [OFOutOfRangeException exception]; tmp = [[OFSecureData alloc] | < | > < | > | | | | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | uint32_t *tmpItems, *bufferItems; if (param.costFactor > SIZE_MAX - 1 || (param.costFactor + 1) > SIZE_MAX / 128) @throw [OFOutOfRangeException exception]; tmp = [[OFSecureData alloc] initWithCount: (param.costFactor + 1) * 128 itemSize: param.blockSize allowsSwappableMemory: param.allowsSwappableMemory]; tmpItems = tmp.mutableItems; if (param.parallelization > SIZE_MAX / 128) @throw [OFOutOfRangeException exception]; buffer = [[OFSecureData alloc] initWithCount: param.parallelization * 128 itemSize: param.blockSize allowsSwappableMemory: param.allowsSwappableMemory]; bufferItems = buffer.mutableItems; HMAC = [[OFHMAC alloc] initWithHashClass: [OFSHA256Hash class] allowsSwappableMemory: param.allowsSwappableMemory]; OFPBKDF2((OFPBKDF2Parameters){ .HMAC = HMAC, .iterations = 1, .salt = param.salt, .saltLength = param.saltLength, .password = param.password, .passwordLength = param.passwordLength, .key = (unsigned char *)bufferItems, .keyLength = param.parallelization * 128 * param.blockSize, .allowsSwappableMemory = param.allowsSwappableMemory }); for (size_t i = 0; i < param.parallelization; i++) OFScryptROMix(bufferItems + i * 32 * param.blockSize, param.blockSize, param.costFactor, tmpItems); OFPBKDF2((OFPBKDF2Parameters){ .HMAC = HMAC, .iterations = 1, .salt = (unsigned char *)bufferItems, .saltLength = param.parallelization * 128 * param.blockSize, .password = param.password, .passwordLength = param.passwordLength, |
︙ | ︙ |
Modified src/OFSecureData.h from [f20113d2e2] to [6ad4e10f23].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | * deallocated. Check the @ref allowsSwappableMemory property to see * whether a particular OFSecureData might be allocated in swappable * memory. */ OF_SUBCLASSING_RESTRICTED @interface OFSecureData: OFData { | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | * deallocated. Check the @ref allowsSwappableMemory property to see * whether a particular OFSecureData might be allocated in swappable * memory. */ OF_SUBCLASSING_RESTRICTED @interface OFSecureData: OFData { void *_page; bool _allowsSwappableMemory; } /** * @brief Whether the data may be stored in swappable memory. */ @property (readonly, nonatomic) bool allowsSwappableMemory; |
︙ | ︙ | |||
77 78 79 80 81 82 83 | + (instancetype)dataWithCount: (size_t)count allowsSwappableMemory: (bool)allowsSwappableMemory; /** * @brief Creates a new, autoreleased OFSecureData with count items of the * specified item size, all set to zero. * | < > | | | > | < < > | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | + (instancetype)dataWithCount: (size_t)count allowsSwappableMemory: (bool)allowsSwappableMemory; /** * @brief Creates a new, autoreleased OFSecureData with count items of the * specified item size, all set to zero. * * @param count The number of zero items the OFSecureData should contain * @param itemSize The size of a single item in the OFSecureData in bytes * @param allowsSwappableMemory Whether the data may be stored in swappable * memory * @return A new, autoreleased OFSecureData */ + (instancetype)dataWithCount: (size_t)count itemSize: (size_t)itemSize allowsSwappableMemory: (bool)allowsSwappableMemory; + (instancetype)dataWithItems: (const void *)items count: (size_t)count OF_UNAVAILABLE; + (instancetype)dataWithItems: (const void *)items count: (size_t)count itemSize: (size_t)itemSize OF_UNAVAILABLE; + (instancetype)dataWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; + (instancetype)dataWithItemsNoCopy: (void *)items count: (size_t)count itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; #ifdef OF_HAVE_FILES + (instancetype)dataWithContentsOfFile: (OFString *)path OF_UNAVAILABLE; #endif + (instancetype)dataWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE; + (instancetype)dataWithStringRepresentation: (OFString *)string OF_UNAVAILABLE; + (instancetype)dataWithBase64EncodedString: (OFString *)string OF_UNAVAILABLE; |
︙ | ︙ | |||
128 129 130 131 132 133 134 | * * @param itemSize The size of a single item in the OFSecureData in bytes * @param count The number of zero items the OFSecureData should contain * @param allowsSwappableMemory Whether the data may be stored in swappable * memory * @return An initialized OFSecureData */ | | | | > | < < > | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | * * @param itemSize The size of a single item in the OFSecureData in bytes * @param count The number of zero items the OFSecureData should contain * @param allowsSwappableMemory Whether the data may be stored in swappable * memory * @return An initialized OFSecureData */ - (instancetype)initWithCount: (size_t)count itemSize: (size_t)itemSize allowsSwappableMemory: (bool)allowsSwappableMemory OF_DESIGNATED_INITIALIZER; - (instancetype)initWithItems: (const void *)items count: (size_t)count OF_UNAVAILABLE; - (instancetype)initWithItems: (const void *)items count: (size_t)count itemSize: (size_t)itemSize OF_UNAVAILABLE; - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE; #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path OF_UNAVAILABLE; #endif - (instancetype)initWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE; - (instancetype)initWithStringRepresentation: (OFString *)string OF_UNAVAILABLE; - (instancetype)initWithBase64EncodedString: (OFString *)string OF_UNAVAILABLE; |
︙ | ︙ |
Modified src/OFSecureData.m from [8eda9d8f37] to [ea6060539c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #ifdef HAVE_SYS_MMAN_H # include <sys/mman.h> #endif #import "OFSecureData.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFNotImplementedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" | > > > | < < | < < | | | | | | | | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #ifdef HAVE_SYS_MMAN_H # include <sys/mman.h> #endif #import "OFSecureData.h" #import "OFString.h" #import "OFSystemInfo.h" #ifdef OF_HAVE_THREADS # import "OFTLSKey.h" #endif #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFNotImplementedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) static const size_t chunkSize = 16; struct Page { struct Page *next, *previous; void *map; unsigned char *page; }; # if defined(OF_HAVE_COMPILER_TLS) static thread_local struct Page *firstPage = NULL; static thread_local struct Page *lastPage = NULL; static thread_local struct Page **preallocatedPages = NULL; static thread_local size_t numPreallocatedPages = 0; # elif defined(OF_HAVE_THREADS) static OFTLSKey firstPageKey, lastPageKey; static OFTLSKey preallocatedPagesKey, numPreallocatedPagesKey; # else static struct Page *firstPage = NULL; static struct Page *lastPage = NULL; static struct Page **preallocatedPages = NULL; static size_t numPreallocatedPages = 0; # endif static void * mapPages(size_t numPages) { size_t pageSize = [OFSystemInfo pageSize]; |
︙ | ︙ | |||
93 94 95 96 97 98 99 | if (numPages > SIZE_MAX / pageSize) @throw [OFOutOfRangeException exception]; munlock(pointer, numPages * pageSize); munmap(pointer, numPages * pageSize); } | | | > | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > < > | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | if (numPages > SIZE_MAX / pageSize) @throw [OFOutOfRangeException exception]; munlock(pointer, numPages * pageSize); munmap(pointer, numPages * pageSize); } static struct Page * addPage(bool allowPreallocated) { size_t pageSize = [OFSystemInfo pageSize]; size_t mapSize = OFRoundUpToPowerOf2(CHAR_BIT, pageSize / chunkSize) / CHAR_BIT; struct Page *page; # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) struct Page *lastPage; # endif if (allowPreallocated) { # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) uintptr_t numPreallocatedPages = (uintptr_t)OFTLSKeyGet(numPreallocatedPagesKey); # endif if (numPreallocatedPages > 0) { # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) struct Page **preallocatedPages = OFTLSKeyGet(preallocatedPagesKey); # endif numPreallocatedPages--; # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) OFEnsure(OFTLSKeySet(numPreallocatedPagesKey, (void *)numPreallocatedPages) == 0); # endif page = preallocatedPages[numPreallocatedPages]; if (numPreallocatedPages == 0) { OFFreeMemory(preallocatedPages); preallocatedPages = NULL; # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) OFEnsure(OFTLSKeySet(preallocatedPagesKey, preallocatedPages) == 0); # endif } return page; } } page = OFAllocMemory(1, sizeof(*page)); @try { page->map = OFAllocZeroedMemory(1, mapSize); } @catch (id e) { OFFreeMemory(page); @throw e; } @try { page->page = mapPages(1); } @catch (id e) { OFFreeMemory(page->map); OFFreeMemory(page); @throw e; } OFZeroMemory(page->page, pageSize); # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) lastPage = OFTLSKeyGet(lastPageKey); # endif page->previous = lastPage; page->next = NULL; if (lastPage != NULL) lastPage->next = page; # if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS) lastPage = page; if (firstPage == NULL) firstPage = page; # else OFEnsure(OFTLSKeySet(lastPageKey, page) == 0); if (OFTLSKeyGet(firstPageKey) == NULL) OFEnsure(OFTLSKeySet(firstPageKey, page) == 0); # endif return page; } static void removePageIfEmpty(struct Page *page) { unsigned char *map = page->map; size_t pageSize = [OFSystemInfo pageSize]; size_t mapSize = OFRoundUpToPowerOf2(CHAR_BIT, pageSize / chunkSize) / CHAR_BIT; for (size_t i = 0; i < mapSize; i++) if (map[i] != 0) return; unmapPages(page->page, 1); OFFreeMemory(page->map); if (page->previous != NULL) page->previous->next = page->next; if (page->next != NULL) page->next->previous = page->previous; # if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS) if (firstPage == page) firstPage = page->next; if (lastPage == page) lastPage = page->previous; # else if (OFTLSKeyGet(firstPageKey) == page) OFEnsure(OFTLSKeySet(firstPageKey, page->next) == 0); if (OFTLSKeyGet(lastPageKey) == page) OFEnsure(OFTLSKeySet(lastPageKey, page->previous) == 0); # endif OFFreeMemory(page); } static void * allocateMemory(struct Page *page, size_t bytes) { size_t chunks, chunksLeft, pageSize, i, firstChunk; bytes = OFRoundUpToPowerOf2(chunkSize, bytes); chunks = chunksLeft = bytes / chunkSize; firstChunk = 0; pageSize = [OFSystemInfo pageSize]; for (i = 0; i < pageSize / chunkSize; i++) { if (OFBitsetIsSet(page->map, i)) { chunksLeft = chunks; firstChunk = i + 1; continue; } if (--chunksLeft == 0) break; } if (chunksLeft == 0) { for (size_t j = firstChunk; j < firstChunk + chunks; j++) OFBitsetSet(page->map, j); return page->page + (chunkSize * firstChunk); } return NULL; } static void freeMemory(struct Page *page, void *pointer, size_t bytes) { size_t chunks, chunkIndex; bytes = OFRoundUpToPowerOf2(chunkSize, bytes); chunks = bytes / chunkSize; chunkIndex = ((uintptr_t)pointer - (uintptr_t)page->page) / chunkSize; OFZeroMemory(pointer, bytes); for (size_t i = 0; i < chunks; i++) OFBitsetClear(page->map, chunkIndex + i); } #endif @implementation OFSecureData @synthesize allowsSwappableMemory = _allowsSwappableMemory; #if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) && \ !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) + (void)initialize { if (self != [OFSecureData class]) return; if (OFTLSKeyNew(&firstPageKey) != 0 || OFTLSKeyNew(&lastPageKey) != 0 || OFTLSKeyNew(&preallocatedPagesKey) != 0 || OFTLSKeyNew(&numPreallocatedPagesKey) != 0) @throw [OFInitializationFailedException exceptionWithClass: self]; } #endif + (void)preallocateUnswappableMemoryWithSize: (size_t)size { #if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) size_t pageSize = [OFSystemInfo pageSize]; size_t numPages = OFRoundUpToPowerOf2(pageSize, size) / pageSize; # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) struct Page **preallocatedPages = OFTLSKeyGet(preallocatedPagesKey); size_t numPreallocatedPages; # endif size_t i; if (preallocatedPages != NULL) @throw [OFInvalidArgumentException exception]; preallocatedPages = OFAllocZeroedMemory(numPages, sizeof(struct Page)); # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) OFEnsure(OFTLSKeySet(preallocatedPagesKey, preallocatedPages) == 0); # endif @try { for (i = 0; i < numPages; i++) preallocatedPages[i] = addPage(false); } @catch (id e) { for (size_t j = 0; j < i; j++) removePageIfEmpty(preallocatedPages[j]); OFFreeMemory(preallocatedPages); preallocatedPages = NULL; @throw e; } numPreallocatedPages = numPages; # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) OFEnsure(OFTLSKeySet(numPreallocatedPagesKey, (void *)(uintptr_t)numPreallocatedPages) == 0); # endif #else @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; #endif } + (instancetype)dataWithCount: (size_t)count allowsSwappableMemory: (bool)allowsSwappableMemory { return [[[self alloc] initWithCount: count allowsSwappableMemory: allowsSwappableMemory] autorelease]; } + (instancetype)dataWithCount: (size_t)count itemSize: (size_t)itemSize allowsSwappableMemory: (bool)allowsSwappableMemory { return [[[self alloc] initWithCount: count itemSize: itemSize allowsSwappableMemory: allowsSwappableMemory] autorelease]; } + (instancetype)dataWithItems: (const void *)items count: (size_t)count { OF_UNRECOGNIZED_SELECTOR } + (instancetype)dataWithItems: (const void *)items count: (size_t)count itemSize: (size_t)itemSize { OF_UNRECOGNIZED_SELECTOR } + (instancetype)dataWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone { OF_UNRECOGNIZED_SELECTOR } + (instancetype)dataWithItemsNoCopy: (void *)items count: (size_t)count itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone { OF_UNRECOGNIZED_SELECTOR } #ifdef OF_HAVE_FILES + (instancetype)dataWithContentsOfFile: (OFString *)path |
︙ | ︙ | |||
391 392 393 394 395 396 397 | OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithCount: (size_t)count allowsSwappableMemory: (bool)allowsSwappableMemory { | | | | | | | | | | | | | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithCount: (size_t)count allowsSwappableMemory: (bool)allowsSwappableMemory { return [self initWithCount: count itemSize: 1 allowsSwappableMemory: allowsSwappableMemory]; } - (instancetype)initWithCount: (size_t)count itemSize: (size_t)itemSize allowsSwappableMemory: (bool)allowsSwappableMemory { self = [super init]; @try { #if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) size_t pageSize = [OFSystemInfo pageSize]; #endif if (count > SIZE_MAX / itemSize) @throw [OFOutOfRangeException exception]; if (allowsSwappableMemory) { _items = OFAllocMemory(count, itemSize); _freeWhenDone = true; memset(_items, 0, count * itemSize); #if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) } else if (count * itemSize >= pageSize) _items = mapPages(OFRoundUpToPowerOf2(pageSize, count * itemSize) / pageSize); else { # if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) struct Page *lastPage = OFTLSKeyGet(lastPageKey); # endif for (struct Page *page = lastPage; page != NULL; page = page->previous) { _items = allocateMemory(page, count * itemSize); if (_items != NULL) { _page = page; break; } |
︙ | ︙ | |||
451 452 453 454 455 456 457 | #else } else @throw [OFNotImplementedException exceptionWithSelector: _cmd object: nil]; #endif | < > | < < > < > | 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 | #else } else @throw [OFNotImplementedException exceptionWithSelector: _cmd object: nil]; #endif _count = count; _itemSize = itemSize; _allowsSwappableMemory = allowsSwappableMemory; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithItems: (const void *)items count: (size_t)count { OF_INVALID_INIT_METHOD } - (instancetype)initWithItems: (const void *)items count: (size_t)count itemSize: (size_t)itemSize { OF_INVALID_INIT_METHOD } - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count freeWhenDone: (bool)freeWhenDone { OF_INVALID_INIT_METHOD } - (instancetype)initWithItemsNoCopy: (void *)items count: (size_t)count itemSize: (size_t)itemSize freeWhenDone: (bool)freeWhenDone { OF_INVALID_INIT_METHOD } #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path |
︙ | ︙ | |||
527 528 529 530 531 532 533 | #if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) if (!_allowsSwappableMemory) { size_t pageSize = [OFSystemInfo pageSize]; if (_count * _itemSize > pageSize) unmapPages(_items, | | | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 | #if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) if (!_allowsSwappableMemory) { size_t pageSize = [OFSystemInfo pageSize]; if (_count * _itemSize > pageSize) unmapPages(_items, OFRoundUpToPowerOf2(pageSize, _count * _itemSize) / pageSize); else if (_page != NULL) { if (_items != NULL) freeMemory(_page, _items, _count * _itemSize); removePageIfEmpty(_page); } |
︙ | ︙ | |||
556 557 558 559 560 561 562 | @throw [OFOutOfRangeException exception]; return _items + idx * _itemSize; } - (void)zero { | | > | < > | < | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 | @throw [OFOutOfRangeException exception]; return _items + idx * _itemSize; } - (void)zero { OFZeroMemory(_items, _count * _itemSize); } - (id)copy { OFSecureData *copy = [[OFSecureData alloc] initWithCount: _count itemSize: _itemSize allowsSwappableMemory: _allowsSwappableMemory]; memcpy(copy.mutableItems, _items, _count * _itemSize); return copy; } - (id)mutableCopy { OFSecureData *copy = [[OFSecureData alloc] initWithCount: _count itemSize: _itemSize allowsSwappableMemory: _allowsSwappableMemory]; memcpy(copy.mutableItems, _items, _count * _itemSize); return copy; } |
︙ | ︙ |
Modified src/OFSeekableStream.h from [1f7744a123] to [dfe5585e9c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | #endif #import "OFStream.h" OF_ASSUME_NONNULL_BEGIN #if defined(OF_WINDOWS) | | | | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #endif #import "OFStream.h" OF_ASSUME_NONNULL_BEGIN #if defined(OF_WINDOWS) typedef __int64 OFFileOffset; #elif defined(OF_ANDROID) typedef long long OFFileOffset; #elif defined(OF_MORPHOS) typedef signed long long OFFileOffset; #elif defined(OF_HAVE_OFF64_T) typedef off64_t OFFileOffset; #else typedef off_t OFFileOffset; #endif /** * @class OFSeekableStream OFSeekableStream.h ObjFW/OFSeekableStream.h * * @brief A stream that supports seeking. * |
︙ | ︙ | |||
69 70 71 72 73 74 75 | * Value | Description * -----------|--------------------------------------- * `SEEK_SET` | Seek to the specified byte * `SEEK_CUR` | Seek to the current location + offset * `SEEK_END` | Seek to the end of the stream + offset * @return The new offset form the start of the file */ | < | < | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | * Value | Description * -----------|--------------------------------------- * `SEEK_SET` | Seek to the specified byte * `SEEK_CUR` | Seek to the current location + offset * `SEEK_END` | Seek to the end of the stream + offset * @return The new offset form the start of the file */ - (OFFileOffset)seekToOffset: (OFFileOffset)offset whence: (int)whence; /** * @brief Seek the stream on the lowlevel. * * @warning Do not call this directly! * * @note Override this method with your actual seek implementation when * subclassing! * * @param offset The offset to seek to * @param whence From where to seek.@n * Possible values are: * Value | Description * -----------|--------------------------------------- * `SEEK_SET` | Seek to the specified byte * `SEEK_CUR` | Seek to the current location + offset * `SEEK_END` | Seek to the end of the stream + offset * @return The new offset from the start of the file */ - (OFFileOffset)lowlevelSeekToOffset: (OFFileOffset)offset whence: (int)whence; @end OF_ASSUME_NONNULL_END |
Modified src/OFSeekableStream.m from [57a7a2c048] to [9e766aeca1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
36 37 38 39 40 41 42 | @throw e; } } return [super init]; } | < | < | | < | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | @throw e; } } return [super init]; } - (OFFileOffset)lowlevelSeekToOffset: (OFFileOffset)offset whence: (int)whence { OF_UNRECOGNIZED_SELECTOR } - (OFFileOffset)seekToOffset: (OFFileOffset)offset whence: (int)whence { if (whence == SEEK_CUR) offset -= _readBufferLength; offset = [self lowlevelSeekToOffset: offset whence: whence]; OFFreeMemory(_readBufferMemory); _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; return offset; } @end |
Modified src/OFSelectKernelEventObserver.h from [4b0f84060b] to [87e3b347a2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFSelectKernelEventObserver.m from [22b01117bc] to [14ac36d0e0].
1 | /* | < < | | | > < < > > > > > > > > | < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #define __NO_EXT_QNX #include "platform.h" #ifdef OF_WINDOWS /* Win32 has a ridiculous default of 64, even though it supports much more. */ # define FD_SETSIZE 1024 #endif #include <errno.h> #include <string.h> #include <sys/time.h> #import "OFSelectKernelEventObserver.h" #import "OFArray.h" #import "OFSocket+Private.h" #import "OFInitializationFailedException.h" #import "OFObserveFailedException.h" #import "OFOutOfRangeException.h" #ifdef OF_AMIGAOS # include <proto/exec.h> #endif #ifdef OF_HPUX /* FD_SET causes warnings on HP-UX/IA64. */ # pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif @implementation OFSelectKernelEventObserver - (instancetype)init { self = [super init]; @try { FD_ZERO(&_readFDs); FD_ZERO(&_writeFDs); #ifdef OF_AMIGAOS _maxFD = -1; #else # ifndef OF_WINDOWS if (_cancelFD[0] >= (int)FD_SETSIZE) @throw [OFInitializationFailedException exceptionWithClass: self.class]; # endif FD_SET(_cancelFD[0], &_readFDs); if (_cancelFD[0] > INT_MAX) @throw [OFOutOfRangeException exception]; _maxFD = (int)_cancelFD[0]; #endif |
︙ | ︙ | |||
91 92 93 94 95 96 97 | if (fd >= (int)FD_SETSIZE) @throw [OFOutOfRangeException exception]; #endif if (fd > _maxFD) _maxFD = fd; | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | if (fd >= (int)FD_SETSIZE) @throw [OFOutOfRangeException exception]; #endif if (fd > _maxFD) _maxFD = fd; FD_SET((OFSocketHandle)fd, &_readFDs); [super addObjectForReading: object]; } - (void)addObjectForWriting: (id <OFReadyForWritingObserving>)object { int fd = object.fileDescriptorForWriting; |
︙ | ︙ | |||
115 116 117 118 119 120 121 | if (fd >= (int)FD_SETSIZE) @throw [OFOutOfRangeException exception]; #endif if (fd > _maxFD) _maxFD = fd; | | | | | > | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | if (fd >= (int)FD_SETSIZE) @throw [OFOutOfRangeException exception]; #endif if (fd > _maxFD) _maxFD = fd; FD_SET((OFSocketHandle)fd, &_writeFDs); [super addObjectForWriting: object]; } - (void)removeObjectForReading: (id <OFReadyForReadingObserving>)object { /* TODO: Adjust _maxFD */ int fd = object.fileDescriptorForReading; if (fd < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: EBADF]; #ifndef OF_WINDOWS if (fd >= (int)FD_SETSIZE) @throw [OFOutOfRangeException exception]; #endif FD_CLR((OFSocketHandle)fd, &_readFDs); [super removeObjectForReading: object]; } - (void)removeObjectForWriting: (id <OFReadyForWritingObserving>)object { /* TODO: Adjust _maxFD */ int fd = object.fileDescriptorForWriting; if (fd < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: EBADF]; #ifndef OF_WINDOWS if (fd >= (int)FD_SETSIZE) @throw [OFOutOfRangeException exception]; #endif FD_CLR((OFSocketHandle)fd, &_writeFDs); [super removeObjectForWriting: object]; } - (void)observeForTimeInterval: (OFTimeInterval)timeInterval { fd_set readFDs; fd_set writeFDs; struct timeval timeout; int events; #ifdef OF_AMIGAOS BYTE cancelSignal; ULONG execSignalMask; #endif void *pool; if ([self of_processReadBuffers]) return; #ifdef FD_COPY |
︙ | ︙ | |||
194 195 196 197 198 199 200 | * satisfy the required range, we just cast to int. */ #ifndef OF_WINDOWS timeout.tv_sec = (time_t)timeInterval; #else timeout.tv_sec = (long)timeInterval; #endif | | | | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | * satisfy the required range, we just cast to int. */ #ifndef OF_WINDOWS timeout.tv_sec = (time_t)timeInterval; #else timeout.tv_sec = (long)timeInterval; #endif timeout.tv_usec = (int)((timeInterval - timeout.tv_sec) * 1000000); #ifdef OF_AMIGAOS if ((cancelSignal = AllocSignal(-1)) == (BYTE)-1) @throw [OFObserveFailedException exceptionWithObserver: self errNo: EAGAIN]; execSignalMask = _execSignalMask | (1ul << cancelSignal); Forbid(); |
︙ | ︙ | |||
225 226 227 228 229 230 231 | events = select(_maxFD + 1, &readFDs, &writeFDs, NULL, (timeInterval != -1 ? &timeout : NULL)); #endif if (events < 0) @throw [OFObserveFailedException exceptionWithObserver: self | | | | | | | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | events = select(_maxFD + 1, &readFDs, &writeFDs, NULL, (timeInterval != -1 ? &timeout : NULL)); #endif if (events < 0) @throw [OFObserveFailedException exceptionWithObserver: self errNo: OFSocketErrNo()]; #ifdef OF_AMIGAOS if (execSignalMask != 0 && [_delegate respondsToSelector: @selector(execSignalWasReceived:)]) [_delegate execSignalWasReceived: execSignalMask]; #else if (FD_ISSET(_cancelFD[0], &readFDs)) { char buffer; # ifdef OF_HAVE_PIPE OFEnsure(read(_cancelFD[0], &buffer, 1) == 1); # else OFEnsure(recvfrom(_cancelFD[0], (void *)&buffer, 1, 0, NULL, NULL) == 1); # endif } #endif pool = objc_autoreleasePoolPush(); for (id <OFReadyForReadingObserving> object in [[_readObjects copy] autorelease]) { void *pool2 = objc_autoreleasePoolPush(); int fd = object.fileDescriptorForReading; if (FD_ISSET((OFSocketHandle)fd, &readFDs) && [_delegate respondsToSelector: @selector(objectIsReadyForReading:)]) [_delegate objectIsReadyForReading: object]; objc_autoreleasePoolPop(pool2); } for (id <OFReadyForWritingObserving> object in [[_writeObjects copy] autorelease]) { void *pool2 = objc_autoreleasePoolPush(); int fd = object.fileDescriptorForWriting; if (FD_ISSET((OFSocketHandle)fd, &writeFDs) && [_delegate respondsToSelector: @selector(objectIsReadyForWriting:)]) [_delegate objectIsReadyForWriting: object]; objc_autoreleasePoolPop(pool2); } objc_autoreleasePoolPop(pool); } @end |
Modified src/OFSequencedPacketSocket+Private.h from [a194b9d55d] to [779ca7e02d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFSequencedPacketSocket.h from [d3b63ac877] to [c4199b3715].
1 | /* | < < | < | | < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFKernelEventObserver.h" #import "OFRunLoop.h" #import "OFSocket.h" OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFData; @class OFSequencedPacketSocket; #ifdef OF_HAVE_BLOCKS /** * @brief A block which is called when a packet has been received. * * @param length The length of the packet * @param exception An exception which occurred while receiving or `nil` on * success * @return A bool whether the same block should be used for the next receive */ typedef bool (^OFSequencedPacketSocketAsyncReceiveBlock)(size_t length, id _Nullable exception); /** * @brief A block which is called when a packet has been sent. * * @param exception An exception which occurred while reading or `nil` on * success * @return The data to repeat the send with or nil if it should not repeat */ typedef OFData *_Nullable (^OFSequencedPacketSocketAsyncSendDataBlock)( id _Nullable exception); /** * @brief A block which is called when the socket accepted a connection. * * @param acceptedSocket The socket which has been accepted * @param exception An exception which occurred while accepting the socket or * `nil` on success * @return A bool whether the same block should be used for the next incoming * connection */ typedef bool (^OFSequencedPacketSocketAsyncAcceptBlock)( OFSequencedPacketSocket *acceptedSocket, id _Nullable exception); #endif /** * @protocol OFSequencedPacketSocketDelegate OFSequencedPacketSocket.h \ * ObjFW/OFSequencedPacketSocket.h * |
︙ | ︙ | |||
125 126 127 128 129 130 131 | * so context can be associated with a socket. Using a socket in more * than one thread at the same time is not thread-safe, even if copy * was called to create one "instance" for every thread! */ @interface OFSequencedPacketSocket: OFObject <OFCopying, OFReadyForReadingObserving, OFReadyForWritingObserving> { | | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | * so context can be associated with a socket. Using a socket in more * than one thread at the same time is not thread-safe, even if copy * was called to create one "instance" for every thread! */ @interface OFSequencedPacketSocket: OFObject <OFCopying, OFReadyForReadingObserving, OFReadyForWritingObserving> { OFSocketHandle _socket; bool _canBlock, _listening; OFSocketAddress _remoteAddress; id _Nullable _delegate; OF_RESERVE_IVARS(OFSequencedPacketSocket, 4) } /** * @brief Whether the socket can block. * |
︙ | ︙ | |||
149 150 151 152 153 154 155 | @property (readonly, nonatomic, getter=isListening) bool listening; /** * @brief The remote address. * * @note This only works for accepted sockets! */ | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | @property (readonly, nonatomic, getter=isListening) bool listening; /** * @brief The remote address. * * @note This only works for accepted sockets! */ @property (readonly, nonatomic) const OFSocketAddress *remoteAddress; /** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ |
︙ | ︙ | |||
176 177 178 179 180 181 182 | * * If the buffer is too small, the receive operation fails. * * @param buffer The buffer to write the packet to * @param length The length of the buffer * @return The length of the received packet */ | | < | < | < | | < | < | | | < | | < | < < | | < | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | * * If the buffer is too small, the receive operation fails. * * @param buffer The buffer to write the packet to * @param length The length of the buffer * @return The length of the received packet */ - (size_t)receiveIntoBuffer: (void *)buffer length: (size_t)length; /** * @brief Asynchronously receives a packet and stores it into the specified * buffer. * * If the buffer is too small, the receive operation fails. * * @param buffer The buffer to write the packet to * @param length The length of the buffer */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length; /** * @brief Asynchronously receives a packet and stores it into the specified * buffer. * * If the buffer is too small, the receive operation fails. * * @param buffer The buffer to write the packet to * @param length The length of the buffer * @param runLoopMode The run loop mode in which to perform the async receive */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode; #ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously receives a packet and stores it into the specified * buffer. * * If the buffer is too small, the receive operation fails. * * @param buffer The buffer to write the packet to * @param length The length of the buffer * @param block The block to call when the packet has been received. If the * block returns true, it will be called again with the same * buffer and maximum length when more packets have been received. * If you want the next method in the queue to handle the packet * received next, you need to return false from the method. */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length block: (OFSequencedPacketSocketAsyncReceiveBlock)block; /** * @brief Asynchronously receives a packet and stores it into the specified * buffer. * * If the buffer is too small, the receive operation fails. * * @param buffer The buffer to write the packet to * @param length The length of the buffer * @param runLoopMode The run loop mode in which to perform the async receive * @param block The block to call when the packet has been received. If the * block returns true, it will be called again with the same * buffer and maximum length when more packets have been received. * If you want the next method in the queue to handle the packet * received next, you need to return false from the method. */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode block: (OFSequencedPacketSocketAsyncReceiveBlock)block; #endif /** * @brief Sends the specified packet. * * @param buffer The buffer to send as a packet * @param length The length of the buffer */ - (void)sendBuffer: (const void *)buffer length: (size_t)length; /** * @brief Asynchronously sends the specified packet. * * @param data The data to send as a packet */ - (void)asyncSendData: (OFData *)data; /** * @brief Asynchronously sends the specified packet. * * @param data The data to send as a packet * @param runLoopMode The run loop mode in which to perform the async send */ - (void)asyncSendData: (OFData *)data runLoopMode: (OFRunLoopMode)runLoopMode; #ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously sends the specified packet. * * @param data The data to send as a packet * @param block The block to call when the packet has been sent. It should * return the data for the next send with the same callback or nil * if it should not repeat. */ - (void)asyncSendData: (OFData *)data block: (OFSequencedPacketSocketAsyncSendDataBlock)block; /** * @brief Asynchronously sends the specified packet. * * @param data The data to send as a packet * @param runLoopMode The run loop mode in which to perform the async send * @param block The block to call when the packet has been sent. It should * return the data for the next send with the same callback or nil * if it should not repeat. */ - (void)asyncSendData: (OFData *)data runLoopMode: (OFRunLoopMode)runLoopMode block: (OFSequencedPacketSocketAsyncSendDataBlock)block; #endif /** * @brief Listen on the socket. * * @param backlog Maximum length for the queue of pending connections. */ |
︙ | ︙ | |||
331 332 333 334 335 336 337 | - (void)asyncAccept; /** * @brief Asynchronously accept an incoming connection. * * @param runLoopMode The run loop mode in which to perform the async accept */ | | | < > | | | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | - (void)asyncAccept; /** * @brief Asynchronously accept an incoming connection. * * @param runLoopMode The run loop mode in which to perform the async accept */ - (void)asyncAcceptWithRunLoopMode: (OFRunLoopMode)runLoopMode; #ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously accept an incoming connection. * * @param block The block to execute when a new connection has been accepted. * Returns whether the next incoming connection should be accepted * by the specified block as well. */ - (void)asyncAcceptWithBlock: (OFSequencedPacketSocketAsyncAcceptBlock)block; /** * @brief Asynchronously accept an incoming connection. * * @param runLoopMode The run loop mode in which to perform the async accept * @param block The block to execute when a new connection has been accepted. * Returns whether the next incoming connection should be accepted * by the specified block as well. */ - (void) asyncAcceptWithRunLoopMode: (OFRunLoopMode)runLoopMode block: (OFSequencedPacketSocketAsyncAcceptBlock)block; #endif /** * @brief Cancels all pending asynchronous requests on the socket. */ - (void)cancelAsyncRequests; |
︙ | ︙ |
Modified src/OFSequencedPacketSocket.m from [395d4dcdd4] to [da50d869cb].
1 | /* | < < | > > > > > > > < < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #ifndef _XOPEN_SOURCE_EXTENDED # define _XOPEN_SOURCE_EXTENDED #endif #define _HPUX_ALT_XOPEN_SOCKET_API #include <assert.h> #include <errno.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFSequencedPacketSocket.h" #import "OFSequencedPacketSocket+Private.h" #import "OFData.h" #import "OFRunLoop+Private.h" #import "OFRunLoop.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFAcceptFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFListenFailedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFSetOptionFailedException.h" #import "OFWriteFailedException.h" @implementation OFSequencedPacketSocket @synthesize listening = _listening, delegate = _delegate; + (void)initialize { if (self != [OFSequencedPacketSocket class]) return; if (!OFSocketInit()) @throw [OFInitializationFailedException exceptionWithClass: self]; } + (instancetype)socket { return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; @try { if (self.class == [OFSequencedPacketSocket class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } _socket = OFInvalidSocketHandle; _canBlock = true; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_socket != OFInvalidSocketHandle) [self close]; [super dealloc]; } #ifndef OF_WII - (int)of_socketError { int errNo; socklen_t len = sizeof(errNo); if (getsockopt(_socket, SOL_SOCKET, SO_ERROR, (char *)&errNo, &len) != 0) return OFSocketErrNo(); return errNo; } #endif - (id)copy { |
︙ | ︙ | |||
129 130 131 132 133 134 135 | if (fcntl(_socket, F_SETFL, flags) == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; _canBlock = canBlock; #elif defined(OF_WINDOWS) | | | | < | | | | < | | < | | < | | | < | | < | | | | < | < | | | | | | | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | if (fcntl(_socket, F_SETFL, flags) == -1) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: errno]; _canBlock = canBlock; #elif defined(OF_WINDOWS) u_long v = !canBlock; if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: OFSocketErrNo()]; _canBlock = canBlock; #else OF_UNRECOGNIZED_SELECTOR #endif } - (size_t)receiveIntoBuffer: (void *)buffer length: (size_t)length { ssize_t ret; if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; #ifndef OF_WINDOWS if ((ret = recv(_socket, buffer, length, 0)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: OFSocketErrNo()]; #else if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((ret = recv(_socket, buffer, (int)length, 0)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: OFSocketErrNo()]; #endif return ret; } - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length { [self asyncReceiveIntoBuffer: buffer length: length runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode { [OFRunLoop of_addAsyncReceiveForSequencedPacketSocket: self buffer: buffer length: length mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length block: (OFSequencedPacketSocketAsyncReceiveBlock)block { [self asyncReceiveIntoBuffer: buffer length: length runLoopMode: OFDefaultRunLoopMode block: block]; } - (void) asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode block: (OFSequencedPacketSocketAsyncReceiveBlock)block { [OFRunLoop of_addAsyncReceiveForSequencedPacketSocket: self buffer: buffer length: length mode: runLoopMode block: block delegate: nil]; } #endif - (void)sendBuffer: (const void *)buffer length: (size_t)length { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; #ifndef OF_WINDOWS ssize_t bytesWritten; if (length > SSIZE_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = send(_socket, (void *)buffer, length, 0)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: OFSocketErrNo()]; #else int bytesWritten; if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = send(_socket, buffer, (int)length, 0)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: OFSocketErrNo()]; #endif if ((size_t)bytesWritten != length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; } - (void)asyncSendData: (OFData *)data { [self asyncSendData: data runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncSendData: (OFData *)data runLoopMode: (OFRunLoopMode)runLoopMode { [OFRunLoop of_addAsyncSendForSequencedPacketSocket: self data: data mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncSendData: (OFData *)data block: (OFSequencedPacketSocketAsyncSendDataBlock)block { [self asyncSendData: data runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncSendData: (OFData *)data runLoopMode: (OFRunLoopMode)runLoopMode block: (OFSequencedPacketSocketAsyncSendDataBlock)block { [OFRunLoop of_addAsyncSendForSequencedPacketSocket: self data: data mode: runLoopMode block: block delegate: nil]; } #endif - (void)listen { [self listenWithBacklog: SOMAXCONN]; } - (void)listenWithBacklog: (int)backlog { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; if (listen(_socket, backlog) == -1) @throw [OFListenFailedException exceptionWithSocket: self backlog: backlog errNo: OFSocketErrNo()]; _listening = true; } - (instancetype)accept { OFSequencedPacketSocket *client = |
︙ | ︙ | |||
335 336 337 338 339 340 341 | client->_remoteAddress.length = (socklen_t)sizeof(client->_remoteAddress.sockaddr); #if defined(HAVE_PACCEPT) && defined(SOCK_CLOEXEC) if ((client->_socket = paccept(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length, NULL, SOCK_CLOEXEC)) == | | | | > | | | | | | | < | | | < | < > | | | | | | | | | | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | client->_remoteAddress.length = (socklen_t)sizeof(client->_remoteAddress.sockaddr); #if defined(HAVE_PACCEPT) && defined(SOCK_CLOEXEC) if ((client->_socket = paccept(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length, NULL, SOCK_CLOEXEC)) == OFInvalidSocketHandle) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: OFSocketErrNo()]; #elif defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) if ((client->_socket = accept4(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length, SOCK_CLOEXEC)) == OFInvalidSocketHandle) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: OFSocketErrNo()]; #else if ((client->_socket = accept(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length)) == OFInvalidSocketHandle) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: OFSocketErrNo()]; # if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(client->_socket, F_GETFD, 0)) != -1) fcntl(client->_socket, F_SETFD, flags | FD_CLOEXEC); # endif #endif assert(client->_remoteAddress.length <= (socklen_t)sizeof(client->_remoteAddress.sockaddr)); switch (client->_remoteAddress.sockaddr.sockaddr.sa_family) { case AF_INET: client->_remoteAddress.family = OFSocketAddressFamilyIPv4; break; #ifdef OF_HAVE_IPV6 case AF_INET6: client->_remoteAddress.family = OFSocketAddressFamilyIPv6; break; #endif #ifdef OF_HAVE_IPX case AF_IPX: client->_remoteAddress.family = OFSocketAddressFamilyIPX; break; #endif default: client->_remoteAddress.family = OFSocketAddressFamilyUnknown; break; } return client; } - (void)asyncAccept { [self asyncAcceptWithRunLoopMode: OFDefaultRunLoopMode]; } - (void)asyncAcceptWithRunLoopMode: (OFRunLoopMode)runLoopMode { [OFRunLoop of_addAsyncAcceptForSocket: self mode: runLoopMode block: NULL delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncAcceptWithBlock: (OFSequencedPacketSocketAsyncAcceptBlock)block { [self asyncAcceptWithRunLoopMode: OFDefaultRunLoopMode block: block]; } - (void) asyncAcceptWithRunLoopMode: (OFRunLoopMode)runLoopMode block: (OFSequencedPacketSocketAsyncAcceptBlock)block { [OFRunLoop of_addAsyncAcceptForSocket: self mode: runLoopMode block: block delegate: nil]; } #endif - (const OFSocketAddress *)remoteAddress { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; if (_remoteAddress.length == 0) @throw [OFInvalidArgumentException exception]; if (_remoteAddress.length > (socklen_t)sizeof(_remoteAddress.sockaddr)) @throw [OFOutOfRangeException exception]; return &_remoteAddress; } - (void)cancelAsyncRequests { [OFRunLoop of_cancelAsyncRequestsForObject: self mode: OFDefaultRunLoopMode]; } - (int)fileDescriptorForReading { #ifndef OF_WINDOWS return _socket; #else if (_socket == OFInvalidSocketHandle) return -1; if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } - (int)fileDescriptorForWriting { #ifndef OF_WINDOWS return _socket; #else if (_socket == OFInvalidSocketHandle) return -1; if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } - (void)close { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; _listening = false; memset(&_remoteAddress, 0, sizeof(_remoteAddress)); closesocket(_socket); _socket = OFInvalidSocketHandle; } @end |
Modified src/OFSerialization.h from [dd863e03f3] to [6913e132ee].
1 | /* | < < | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN @class OFConstantString; @class OFXMLElement; /** * @protocol OFSerialization OFSerialization.h ObjFW/OFSerialization.h * * @brief A protocol for serializing objects. */ |
︙ | ︙ | |||
38 39 40 41 42 43 44 45 46 | * @brief Initializes the object with the specified XML element serialization. * * @param element An OFXMLElement with the serialized object * @return An initialized object */ - (instancetype)initWithSerialization: (OFXMLElement *)element; @end OF_ASSUME_NONNULL_END | > > > > > > > > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | * @brief Initializes the object with the specified XML element serialization. * * @param element An OFXMLElement with the serialized object * @return An initialized object */ - (instancetype)initWithSerialization: (OFXMLElement *)element; @end #ifdef __cplusplus extern "C" { #endif extern OFConstantString *const OFSerializationNS; #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Added src/OFSerialization.m version [0e1e99b940].
> > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFSerialization.h" #import "OFString.h" OFConstantString *const OFSerializationNS = @"https://objfw.nil.im/serialization"; |
Modified src/OFSet.h from [18028f8bc4] to [4c0dd3a76f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
38 39 40 41 42 43 44 | /** * @brief A block for enumerating an OFSet. * * @param object The current object * @param stop A pointer to a variable that can be set to true to stop the * enumeration */ | | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | /** * @brief A block for enumerating an OFSet. * * @param object The current object * @param stop A pointer to a variable that can be set to true to stop the * enumeration */ typedef void (^OFSetEnumerationBlock)(id object, bool *stop); /** * @brief A block for filtering an OFSet. * * @param object The object to inspect * @return Whether the object should be in the filtered set */ typedef bool (^OFSetFilterBlock)(id object); #endif /** * @class OFSet OFSet.h ObjFW/OFSet.h * * @brief An abstract class for an unordered set of unique objects. * |
︙ | ︙ | |||
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | * @brief Initializes an already allocated set with the specified objects. * * @param firstObject The first object for the set * @return An initialized set with the specified objects */ - (instancetype)initWithObjects: (ObjectType)firstObject, ... OF_SENTINEL; /** * @brief Initializes an already allocated set with the specified objects. * * @param objects An array of objects for the set * @param count The number of objects in the specified array * @return An initialized set with the specified objects */ - (instancetype)initWithObjects: (ObjectType const _Nonnull *_Nonnull)objects count: (size_t)count; /** | > > > > > > > > > > > | < < < | | < < < < < < < < < < < < < < < < < < < | | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | * @brief Initializes an already allocated set with the specified objects. * * @param firstObject The first object for the set * @return An initialized set with the specified objects */ - (instancetype)initWithObjects: (ObjectType)firstObject, ... OF_SENTINEL; /** * @brief Initializes an already allocated set with the specified object and * va_list. * * @param firstObject The first object for the set * @param arguments A va_list with the other objects * @return An initialized set with the specified object and va_list */ - (instancetype)initWithObject: (ObjectType)firstObject arguments: (va_list)arguments; /** * @brief Initializes an already allocated set with the specified objects. * * @param objects An array of objects for the set * @param count The number of objects in the specified array * @return An initialized set with the specified objects */ - (instancetype)initWithObjects: (ObjectType const _Nonnull *_Nonnull)objects count: (size_t)count; /** * @brief Returns an OFEnumerator to enumerate through all objects of the set. * * @return An OFEnumerator to enumerate through all objects of the set */ - (OFEnumerator OF_GENERIC(ObjectType) *)objectEnumerator; /** * @brief Returns whether the receiver is a subset of the specified set. * * @return Whether the receiver is a subset of the specified set */ - (bool)isSubsetOfSet: (OFSet OF_GENERIC(ObjectType) *)set; /** * @brief Returns whether the receiver and the specified set have at least one * object in common. * * @return Whether the receiver and the specified set have at least one object * in common */ - (bool)intersectsSet: (OFSet OF_GENERIC(ObjectType) *)set; /** * @brief Creates a new set by creating the union of the receiver and the * specified set. * * @param set The set to create the union with */ - (OFSet OF_GENERIC(ObjectType) *)setByAddingObjectsFromSet: (OFSet OF_GENERIC(ObjectType) *)set; /** * @brief Checks whether the set contains an object equal to the specified * object. * * @param object The object which is checked for being in the set |
︙ | ︙ | |||
237 238 239 240 241 242 243 | * @ref setValue:forKey: is called for each object. * * @note A @ref OFNull value is translated to nil! * * @param value The value for the specified key * @param key The key of the value to set */ | | < | | | | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | * @ref setValue:forKey: is called for each object. * * @note A @ref OFNull value is translated to nil! * * @param value The value for the specified key * @param key The key of the value to set */ - (void)setValue: (nullable id)value forKey: (OFString *)key; #ifdef OF_HAVE_BLOCKS /** * @brief Executes a block for each object in the set. * * @param block The block to execute for each object in the set */ - (void)enumerateObjectsUsingBlock: (OFSetEnumerationBlock)block; /** * @brief Creates a new set, only containing the objects for which the block * returns true. * * @param block A block which determines if the object should be in the new set * @return A new, autoreleased OFSet */ - (OFSet OF_GENERIC(ObjectType) *) filteredSetUsingBlock: (OFSetFilterBlock)block; #endif #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef ObjectType #endif @end OF_ASSUME_NONNULL_END #import "OFMutableSet.h" |
Modified src/OFSet.m from [fd18f62182] to [c2dcb9f429].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
58 59 60 61 62 63 64 | ret = [[OFMapTableSet alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } | | < | < | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | ret = [[OFMapTableSet alloc] initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { return (id)[[OFMapTableSet alloc] initWithObjects: objects count: count]; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { return (id)[[OFMapTableSet alloc] initWithObject: firstObject arguments: arguments]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { |
︙ | ︙ | |||
140 141 142 143 144 145 146 | ret = [[[self alloc] initWithObject: firstObject arguments: arguments] autorelease]; va_end(arguments); return ret; } | | < | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | ret = [[[self alloc] initWithObject: firstObject arguments: arguments] autorelease]; va_end(arguments); return ret; } + (instancetype)setWithObjects: (id const *)objects count: (size_t)count { return [[[self alloc] initWithObjects: objects count: count] autorelease]; } - (instancetype)init { |
︙ | ︙ | |||
173 174 175 176 177 178 179 | } - (instancetype)initWithArray: (OFArray *)array { OF_INVALID_INIT_METHOD } | | < | < | < | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | } - (instancetype)initWithArray: (OFArray *)array { OF_INVALID_INIT_METHOD } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { OF_INVALID_INIT_METHOD } - (instancetype)initWithObjects: (id)firstObject, ... { id ret; va_list arguments; va_start(arguments, firstObject); ret = [self initWithObject: firstObject arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { OF_INVALID_INIT_METHOD } - (instancetype)initWithSerialization: (OFXMLElement *)element { OF_INVALID_INIT_METHOD |
︙ | ︙ | |||
229 230 231 232 233 234 235 | } [ret makeImmutable]; return ret; } | | < | < | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | } [ret makeImmutable]; return ret; } - (void)setValue: (id)value forKey: (OFString *)key { for (id object in self) [object setValue: value forKey: key]; } - (bool)containsObject: (id)object { OF_UNRECOGNIZED_SELECTOR } - (OFEnumerator *)objectEnumerator { OF_UNRECOGNIZED_SELECTOR } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { OFEnumerator *enumerator; int i; memcpy(&enumerator, state->extra, sizeof(enumerator)); |
︙ | ︙ | |||
331 332 333 334 335 336 337 | [ret appendString: [object description]]; if (++i < count) [ret appendString: @",\n"]; objc_autoreleasePoolPop(pool2); } | | < < | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | [ret appendString: [object description]]; if (++i < count) [ret appendString: @",\n"]; objc_autoreleasePoolPop(pool2); } [ret replaceOccurrencesOfString: @"\n" withString: @"\n\t"]; [ret appendString: @"\n)}"]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } |
︙ | ︙ | |||
377 378 379 380 381 382 383 | - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; if ([self isKindOfClass: [OFMutableSet class]]) element = [OFXMLElement elementWithName: @"OFMutableSet" | | | < < < < < < < < < < < < < < < < < < < < < < < < < < | < < | < < < < | | | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; if ([self isKindOfClass: [OFMutableSet class]]) element = [OFXMLElement elementWithName: @"OFMutableSet" namespace: OFSerializationNS]; else element = [OFXMLElement elementWithName: @"OFSet" namespace: OFSerializationNS]; for (id <OFSerialization> object in self) { void *pool2 = objc_autoreleasePoolPush(); [element addChild: object.XMLElementBySerializing]; objc_autoreleasePoolPop(pool2); } [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } - (OFSet *)setByAddingObjectsFromSet: (OFSet *)set { OFMutableSet *new = [[self mutableCopy] autorelease]; [new unionSet: set]; [new makeImmutable]; return new; } - (OFArray *)allObjects { void *pool = objc_autoreleasePoolPush(); OFArray *ret = [[[self objectEnumerator] allObjects] retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (id)anyObject { void *pool = objc_autoreleasePoolPush(); id ret = [[[self objectEnumerator] nextObject] retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } #ifdef OF_HAVE_BLOCKS - (void)enumerateObjectsUsingBlock: (OFSetEnumerationBlock)block { bool stop = false; for (id object in self) { block(object, &stop); if (stop) break; } } - (OFSet *)filteredSetUsingBlock: (OFSetFilterBlock)block { OFMutableSet *ret = [OFMutableSet set]; [self enumerateObjectsUsingBlock: ^ (id object, bool *stop) { if (block(object)) [ret addObject: object]; }]; |
︙ | ︙ |
Modified src/OFSettings.h from [a6f65cccf4] to [372d44cad4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
70 71 72 73 74 75 76 | /** * @brief Sets the specified path to the specified string. * * @param string The string to set * @param path The path to store the string at */ | | < | | | < | | < | < | < | | | | | | | | | | | | | | | < | | | < | | | < | | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | /** * @brief Sets the specified path to the specified string. * * @param string The string to set * @param path The path to store the string at */ - (void)setString: (OFString *)string forPath: (OFString *)path; /** * @brief Sets the specified path to the specified long long. * * @param longLong The long long to set * @param path The path to store the long long at */ - (void)setLongLong: (long long)longLong forPath: (OFString *)path; /** * @brief Sets the specified path to the specified bool. * * @param bool_ The bool to set * @param path The path to store the bool at */ - (void)setBool: (bool)bool_ forPath: (OFString *)path; /** * @brief Sets the specified path to the specified float. * * @param float_ The float to set * @param path The path to store the float at */ - (void)setFloat: (float)float_ forPath: (OFString *)path; /** * @brief Sets the specified path to the specified double. * * @param double_ The double to set * @param path The path to store the double at */ - (void)setDouble: (double)double_ forPath: (OFString *)path; /** * @brief Sets the specified path to the specified array of strings. * * @param array The array of strings to set * @param path The path to store the array of string at */ - (void)setStringArray: (OFArray OF_GENERIC(OFString *) *)array forPath: (OFString *)path; /** * @brief Returns the string for the specified path, or `nil` if the path does * not exist. * * @param path The path for which the string should be returned * @return The string of the specified path */ - (nullable OFString *)stringForPath: (OFString *)path; /** * @brief Returns the string for the specified path, or the default value if * the path does not exist. * * @param path The path for which the string should be returned * @param defaultValue The default value to return if the path does not exist * @return The string of the specified path */ - (nullable OFString *)stringForPath: (OFString *)path defaultValue: (nullable OFString *)defaultValue; /** * @brief Returns the long long for the specified path, or the default value if * the path does not exist. * * @param path The path for which the long long should be returned * @param defaultValue The default value to return if the path does not exist * @return The long long of the specified path */ - (long long)longLongForPath: (OFString *)path defaultValue: (long long)defaultValue; /** * @brief Returns the bool for the specified path, or the default value if the * path does not exist. * * @param path The path for which the bool should be returned * @param defaultValue The default value to return if the path does not exist * @return The bool of the specified path */ - (bool)boolForPath: (OFString *)path defaultValue: (bool)defaultValue; /** * @brief Returns the float for the specified path, or the default value if the * path does not exist. * * @param path The path for which the float should be returned * @param defaultValue The default value to return if the path does not exist * @return The float of the specified path */ - (float)floatForPath: (OFString *)path defaultValue: (float)defaultValue; /** * @brief Returns the double for the specified path, or the default value if * the path does not exist. * * @param path The path for which the double should be returned * @param defaultValue The default value to return if the path does not exist * @return The double of the specified path */ - (double)doubleForPath: (OFString *)path defaultValue: (double)defaultValue; /** * @brief Returns the array of strings for the specified path, or an empty * array if the path does not exist. * * @param path The path for which the array of strings should be returned * @return The array of string values of the specified path */ - (OFArray OF_GENERIC(OFString *) *)stringArrayForPath: (OFString *)path; /** * @brief Removes the value for the specified path. * * @param path The path for which the value should be removed */ - (void)removeValueForPath: (OFString *)path; |
︙ | ︙ |
Modified src/OFSettings.m from [5da0b0a891] to [206814d076].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
46 47 48 49 50 51 52 | - (instancetype)initWithApplicationName: (OFString *)applicationName { self = [super init]; @try { _applicationName = [applicationName copy]; } @catch (id e) { | < > | < < | | < | < | < | | | < | | > > > > > | < | < | < < < < < < | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | - (instancetype)initWithApplicationName: (OFString *)applicationName { self = [super init]; @try { _applicationName = [applicationName copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_applicationName release]; [super dealloc]; } - (void)setString: (OFString *)string forPath: (OFString *)path { OF_UNRECOGNIZED_SELECTOR } - (void)setLongLong: (long long)longLong forPath: (OFString *)path { OF_UNRECOGNIZED_SELECTOR } - (void)setBool: (bool)bool_ forPath: (OFString *)path { OF_UNRECOGNIZED_SELECTOR } - (void)setFloat: (float)float_ forPath: (OFString *)path { OF_UNRECOGNIZED_SELECTOR } - (void)setDouble: (double)double_ forPath: (OFString *)path { OF_UNRECOGNIZED_SELECTOR } - (void)setStringArray: (OFArray OF_GENERIC(OFString *) *)array forPath: (OFString *)path { OF_UNRECOGNIZED_SELECTOR } - (OFString *)stringForPath: (OFString *)path { return [self stringForPath: path defaultValue: nil]; } - (OFString *)stringForPath: (OFString *)path defaultValue: (OFString *)defaultValue { OF_UNRECOGNIZED_SELECTOR } - (long long)longLongForPath: (OFString *)path defaultValue: (long long)defaultValue { OF_UNRECOGNIZED_SELECTOR } - (bool)boolForPath: (OFString *)path defaultValue: (bool)defaultValue { OF_UNRECOGNIZED_SELECTOR } - (float)floatForPath: (OFString *)path defaultValue: (float)defaultValue { OF_UNRECOGNIZED_SELECTOR } - (double)doubleForPath: (OFString *)path defaultValue: (double)defaultValue { OF_UNRECOGNIZED_SELECTOR } - (OFArray OF_GENERIC(OFString *) *)stringArrayForPath: (OFString *)path { OF_UNRECOGNIZED_SELECTOR } - (void)removeValueForPath: (OFString *)path { OF_UNRECOGNIZED_SELECTOR |
︙ | ︙ |
Renamed and modified src/OFDimensionValue.h [76c9d8a875] to src/OFSizeValue.h [d063d8cdb8].
1 | /* | < < | | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" OF_ASSUME_NONNULL_BEGIN @interface OFSizeValue: OFValue { OFSize _size; } - (instancetype)initWithSize: (OFSize)size; @end OF_ASSUME_NONNULL_END |
Renamed and modified src/OFDimensionValue.m [54ce362b98] to src/OFSizeValue.m [86214acf8b].
1 | /* | < < | | | | | | | | < | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFSizeValue.h" #import "OFMethodSignature.h" #import "OFString.h" #import "OFOutOfRangeException.h" @implementation OFSizeValue @synthesize sizeValue = _size; - (instancetype)initWithSize: (OFSize)size { self = [super init]; _size = size; return self; } - (const char *)objCType { return @encode(OFSize); } - (void)getValue: (void *)value size: (size_t)size { if (size != sizeof(_size)) @throw [OFOutOfRangeException exception]; memcpy(value, &_size, sizeof(_size)); } - (OFString *)description { return [OFString stringWithFormat: @"<OFValue: OFSize { %f, %f }>", _size.width, _size.height]; } @end |
Renamed and modified src/socket_helpers.h [76048c8293] to src/OFSocket+Private.h [00458f91c6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | #ifdef HAVE_ARPA_INET_H # include <arpa/inet.h> #endif #ifdef HAVE_NETDB_H # include <netdb.h> #endif | | < < < < | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #ifdef HAVE_ARPA_INET_H # include <arpa/inet.h> #endif #ifdef HAVE_NETDB_H # include <netdb.h> #endif #include "OFSocket.h" #ifndef INADDR_NONE # define INADDR_NONE ((in_addr_t)-1) #endif #ifndef SOMAXCONN /* |
︙ | ︙ | |||
55 56 57 58 59 60 61 | # include <proto/bsdsocket.h> # endif # include <sys/filio.h> # define closesocket(sock) CloseSocket(sock) # define ioctlsocket(fd, req, arg) IoctlSocket(fd, req, arg) # define hstrerror(err) "unknown (no hstrerror)" # define SOCKET_ERROR -1 | | | | < < < < < | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | # include <proto/bsdsocket.h> # endif # include <sys/filio.h> # define closesocket(sock) CloseSocket(sock) # define ioctlsocket(fd, req, arg) IoctlSocket(fd, req, arg) # define hstrerror(err) "unknown (no hstrerror)" # define SOCKET_ERROR -1 # if defined(OF_HAVE_THREADS) && !defined(OF_MORPHOS) # define SocketBase ((struct Library *)OFTLSKeyGet(OFSocketBaseKey)) # ifdef OF_AMIGAOS4 # define ISocket ((struct SocketIFace *)OFTLSKeyGet(OFSocketInterfaceKey)) # endif # endif # ifdef OF_MORPHOS typedef uint32_t in_addr_t; # endif #elif !defined(OF_WINDOWS) && !defined(OF_WII) # define closesocket(sock) close(sock) #endif #ifdef OF_WII # define accept(sock, addr, addrlen) net_accept(sock, addr, addrlen) # define bind(sock, addr, addrlen) net_bind(sock, addr, addrlen) # define closesocket(sock) net_close(sock) # define connect(sock, addr, addrlen) \ net_connect(sock, (struct sockaddr *)addr, addrlen) # define fcntl(fd, cmd, flags) net_fcntl(fd, cmd, flags) |
︙ | ︙ |
Renamed and modified src/socket.h [750c66c5d1] to src/OFSocket.h [fb1a5b55eb].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #ifndef OF_HAVE_SOCKETS # error No sockets available! #endif #include <stdbool.h> #import "OFString.h" #ifdef OF_HAVE_SYS_SOCKET_H # include <sys/socket.h> #endif #ifdef OF_HAVE_NETINET_IN_H # include <netinet/in.h> #endif #ifdef OF_HAVE_NETINET_TCP_H # include <netinet/tcp.h> #endif | > > > < < < | | > > > > < < < | > | > > > > > < < < < | | | | > > | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | #ifndef OF_HAVE_SOCKETS # error No sockets available! #endif #include <stdbool.h> #import "OFString.h" #if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) # import "OFTLSKey.h" #endif #ifdef OF_HAVE_SYS_SOCKET_H # include <sys/socket.h> #endif #ifdef OF_HAVE_NETINET_IN_H # include <netinet/in.h> #endif #ifdef OF_HAVE_NETINET_TCP_H # include <netinet/tcp.h> #endif #ifdef OF_HAVE_NETIPX_IPX_H # include <netipx/ipx.h> #endif #ifdef OF_HAVE_SYS_UN_H # include <sys/un.h> #endif #ifdef OF_HAVE_AFUNIX_H # include <afunix.h> #endif #ifdef OF_WINDOWS # include <windows.h> # include <ws2tcpip.h> # ifdef OF_HAVE_IPX # include <wsipx.h> # endif #endif /** @file */ #ifdef OF_WII # include <network.h> #endif #ifdef OF_PSP # include <stdint.h> #endif #import "macros.h" OF_ASSUME_NONNULL_BEGIN #ifndef OF_WINDOWS typedef int OFSocketHandle; static const OFSocketHandle OFInvalidSocketHandle = -1; #else typedef SOCKET OFSocketHandle; static const OFSocketHandle OFInvalidSocketHandle = INVALID_SOCKET; #endif #ifdef OF_WINDOWS typedef short sa_family_t; #endif #ifdef OF_WII typedef u8 sa_family_t; #endif #ifdef OF_MORPHOS typedef long socklen_t; typedef u_char sa_family_t; typedef u_short in_port_t; #endif /** * @brief A socket address family. */ typedef enum { /** An unknown address family. */ OFSocketAddressFamilyUnknown, /** IPv4 */ OFSocketAddressFamilyIPv4, /** IPv6 */ OFSocketAddressFamilyIPv6, /** IPX */ OFSocketAddressFamilyIPX, /** UNIX */ OFSocketAddressFamilyUNIX, /** Any address family */ OFSocketAddressFamilyAny = 255 } OFSocketAddressFamily; #ifndef OF_HAVE_IPV6 struct sockaddr_in6 { sa_family_t sin6_family; in_port_t sin6_port; uint32_t sin6_flowinfo; struct in6_addr { |
︙ | ︙ | |||
130 131 132 133 134 135 136 137 | # define IPX_NODE_LEN 6 # define sipx_family sa_family # define sipx_network sa_netnum # define sipx_node sa_nodenum # define sipx_port sa_socket #endif /** | > > > > > > > | | | > < | | > | < | | | < | | | < | | > | > > > > > > > > | < | | | | | | | < < | | | | | < | | | | | | | | < | | < | > > > > > > > > > | | | | | | | | | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | # define IPX_NODE_LEN 6 # define sipx_family sa_family # define sipx_network sa_netnum # define sipx_node sa_nodenum # define sipx_port sa_socket #endif #if !defined(OF_HAVE_UNIX_SOCKETS) && !defined(OF_MORPHOS) && !defined(OF_MINT) struct sockaddr_un { sa_family_t sun_family; char sun_path[108]; }; #endif /** * @struct OFSocketAddress OFSocket.h ObjFW/OFSocket.h * * @brief A struct which represents a host / port pair for a socket. */ typedef struct OF_BOXABLE { /* * Even though struct sockaddr contains the family, we need to use our * own family, as we need to support storing an IPv6 address on systems * that don't support IPv6. These may not have AF_INET6 defined and we * can't just define it, as the value is system-dependent and might * clash with an existing value. */ OFSocketAddressFamily family; union { struct sockaddr sockaddr; struct sockaddr_in in; struct sockaddr_in6 in6; struct sockaddr_ipx ipx; struct sockaddr_un un; } sockaddr; socklen_t length; } OFSocketAddress; #ifdef __cplusplus extern "C" { #endif /** * @brief Parses the specified IP (either v4 or v6) and port into an * @ref OFSocketAddress. * * @param IP The IP to parse * @param port The port to use * @return The parsed IP and port as an OFSocketAddress */ extern OFSocketAddress OFSocketAddressParseIP(OFString *IP, uint16_t port); /** * @brief Parses the specified IPv4 and port into an @ref OFSocketAddress. * * @param IP The IPv4 to parse * @param port The port to use * @return The parsed IPv4 and port as an OFSocketAddress */ extern OFSocketAddress OFSocketAddressParseIPv4(OFString *IP, uint16_t port); /** * @brief Parses the specified IPv6 and port into an @ref OFSocketAddress. * * @param IP The IPv6 to parse * @param port The port to use * @return The parsed IPv6 and port as an OFSocketAddress */ extern OFSocketAddress OFSocketAddressParseIPv6(OFString *IP, uint16_t port); /** * @brief Creates an IPX address for the specified node, network and port. * * @param node The node in the IPX network * @param network The IPX network * @param port The IPX port (sometimes called socket number) on the node * @return An IPX socket address with the specified node, network and port. */ extern OFSocketAddress OFSocketAddressMakeIPX( const unsigned char node[_Nonnull IPX_NODE_LEN], uint32_t network, uint16_t port); /** * @brief Creates a UNIX socket address from the specified path. * * @param path The path of the UNIX socket * @return A UNIX socket address with the specified path */ extern OFSocketAddress OFSocketAddressMakeUNIX(OFString *path); /** * @brief Compares two OFSocketAddress for equality. * * @param address1 The address to compare with the second address * @param address2 The second address * @return Whether the two addresses are equal */ extern bool OFSocketAddressEqual(const OFSocketAddress *_Nonnull address1, const OFSocketAddress *_Nonnull address2); /** * @brief Returns the hash for the specified @ref OFSocketAddress. * * @param address The address to hash * @return The hash for the specified OFSocketAddress */ extern unsigned long OFSocketAddressHash( const OFSocketAddress *_Nonnull address); /** * @brief Converts the specified @ref OFSocketAddress to a string. * * @param address The address to convert to a string * @return The address as an IP string */ extern OFString *_Nonnull OFSocketAddressString( const OFSocketAddress *_Nonnull address); /** * @brief Sets the port of the specified @ref OFSocketAddress, independent of * the address family used. * * @param address The address on which to set the port * @param port The port to set on the address */ extern void OFSocketAddressSetPort(OFSocketAddress *_Nonnull address, uint16_t port); /** * @brief Returns the port of the specified @ref OFSocketAddress, independent of * the address family used. * * @param address The address on which to get the port * @return The port of the address */ extern uint16_t OFSocketAddressPort(const OFSocketAddress *_Nonnull address); /** * @brief Sets the IPX network of the specified @ref OFSocketAddress. * * @param address The address on which to set the IPX network * @param network The IPX network to set on the address */ extern void OFSocketAddressSetIPXNetwork(OFSocketAddress *_Nonnull address, uint32_t network); /** * @brief Returns the IPX network of the specified @ref OFSocketAddress. * * @param address The address on which to get the IPX network * @return The IPX network of the address */ extern uint32_t OFSocketAddressIPXNetwork( const OFSocketAddress *_Nonnull address); /** * @brief Sets the IPX node of the specified @ref OFSocketAddress. * * @param address The address on which to set the IPX node * @param node The IPX node to set on the address */ extern void OFSocketAddressSetIPXNode(OFSocketAddress *_Nonnull address, const unsigned char node[_Nonnull IPX_NODE_LEN]); /** * @brief Gets the IPX node of the specified @ref OFSocketAddress. * * @param address The address on which to get the IPX node * @param node A byte array to store the IPX node of the address */ extern void OFSocketAddressIPXNode(const OFSocketAddress *_Nonnull address, unsigned char node[_Nonnull IPX_NODE_LEN]); /** * @brief Gets the UNIX socket path of the specified @ref OFSocketAddress. * * @param address The address on which to get the UNIX socket path * @return The UNIX socket path */ extern OFString *_Nullable OFSocketAddressUNIXPath( const OFSocketAddress *_Nonnull address); extern bool OFSocketInit(void); #if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS) extern void OFSocketDeinit(void); #endif extern int OFSocketErrNo(void); #if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) extern int OFGetSockName(OFSocketHandle sock, struct sockaddr *restrict addr, socklen_t *restrict addrLen); #endif #if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS) extern OFTLSKey OFSocketBaseKey; # ifdef OF_AMIGAOS4 extern OFTLSKey OFSocketInterfaceKey; # endif #endif #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Renamed and modified src/socket.m [2544d0730b] to src/OFSocket.m [8f11763ca5].
1 | /* | < < | > > > > > > > > > > > > > > > < < < < < < < < < < < | > > | > > > > | | > | > | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #ifndef _XOPEN_SOURCE_EXTENDED # define _XOPEN_SOURCE_EXTENDED #endif #define _HPUX_ALT_XOPEN_SOCKET_API #ifdef OF_NINTENDO_3DS # include <malloc.h> /* For memalign() */ #endif #include <errno.h> #import "OFArray.h" #import "OFCharacterSet.h" #import "OFLocale.h" #ifdef OF_HAVE_THREADS # import "OFMutex.h" #endif #import "OFOnce.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFString.h" #ifdef OF_HAVE_THREADS # import "OFTLSKey.h" #endif #import "OFException.h" /* For some E* -> WSAE* defines */ #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFLockFailedException.h" #import "OFOutOfRangeException.h" #import "OFUnlockFailedException.h" #ifdef OF_AMIGAOS # include <proto/exec.h> #endif #ifdef OF_NINTENDO_3DS # include <3ds/types.h> # include <3ds/services/soc.h> #endif #if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS)) static OFMutex *mutex; static void releaseMutex(void) { [mutex release]; } #endif #if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS) static bool initSuccessful = false; #endif #ifdef OF_AMIGAOS # if defined(OF_HAVE_THREADS) && !defined(OF_MORPHOS) OFTLSKey OFSocketBaseKey; # ifdef OF_AMIGAOS4 OFTLSKey OFSocketInterfaceKey; # endif # else struct Library *SocketBase; # ifdef OF_AMIGAOS4 struct SocketIFace *ISocket = NULL; # endif # endif #endif #if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS) OF_CONSTRUCTOR() { if (OFTLSKeyNew(&OFSocketBaseKey) != 0) @throw [OFInitializationFailedException exception]; # ifdef OF_AMIGAOS4 if (OFTLSKeyNew(&OFSocketInterfaceKey) != 0) @throw [OFInitializationFailedException exception]; # endif } #endif #if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS) static void init(void) { # if defined(OF_WINDOWS) WSADATA wsa; if (WSAStartup(MAKEWORD(2, 0), &wsa)) |
︙ | ︙ | |||
118 119 120 121 122 123 124 | if (socInit(ctx, 0x100000) != 0) return; atexit((void (*)(void))socExit); # endif | | | | | < > < > | | | | | | | | | | | | < | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | if (socInit(ctx, 0x100000) != 0) return; atexit((void (*)(void))socExit); # endif # if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS)) mutex = [[OFMutex alloc] init]; atexit(releaseMutex); # ifdef OF_WII if (OFSpinlockNew(&spinlock) != 0) return; # endif # endif initSuccessful = true; } OF_DESTRUCTOR() { # ifdef OF_AMIGAOS # ifdef OF_AMIGAOS4 if (ISocket != NULL) DropInterface((struct Interface *)ISocket); # endif if (SocketBase != NULL) CloseLibrary(SocketBase); # endif } #endif bool OFSocketInit(void) { #if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS) static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, init); return initSuccessful; #else struct Library *socketBase; # ifdef OF_AMIGAOS4 struct SocketIFace *socketInterface; # endif # ifdef OF_AMIGAOS4 if ((socketInterface = OFTLSKeyGet(OFSocketInterfaceKey)) != NULL) # else if ((socketBase = OFTLSKeyGet(OFSocketBaseKey)) != NULL) # endif return true; if ((socketBase = OpenLibrary("bsdsocket.library", 4)) == NULL) return false; # ifdef OF_AMIGAOS4 if ((socketInterface = (struct SocketIFace *) GetInterface(socketBase, "main", 1, NULL)) == NULL) { CloseLibrary(socketBase); return false; } # endif if (OFTLSKeySet(OFSocketBaseKey, socketBase) != 0) { CloseLibrary(socketBase); # ifdef OF_AMIGAOS4 DropInterface((struct Interface *)socketInterface); # endif return false; } # ifdef OF_AMIGAOS4 if (OFTLSKeySet(OFSocketInterfaceKey, socketInterface) != 0) { CloseLibrary(socketBase); DropInterface((struct Interface *)socketInterface); return false; } # endif return true; #endif } #if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS) void OFSocketDeinit(void) { struct Library *socketBase = OFTLSKeyGet(OFSocketBaseKey); # ifdef OF_AMIGAOS4 struct SocketIFace *socketInterface = OFTLSKeyGet(OFSocketInterfaceKey); if (socketInterface != NULL) DropInterface((struct Interface *)socketInterface); # endif if (socketBase != NULL) CloseLibrary(socketBase); } #endif int OFSocketErrNo() { #if defined(OF_WINDOWS) switch (WSAGetLastError()) { case WSAEACCES: return EACCES; case WSAEADDRINUSE: return EADDRINUSE; |
︙ | ︙ | |||
317 318 319 320 321 322 323 | #else return errno; #endif } #ifndef OF_WII int | | | < < | < < | | < | | | | | | | | | | | | | | | 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | #else return errno; #endif } #ifndef OF_WII int OFGetSockName(OFSocketHandle sock, struct sockaddr *restrict addr, socklen_t *restrict addrLen) { int ret; # if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS)) [mutex lock]; # endif ret = getsockname(sock, addr, addrLen); # if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS)) [mutex unlock]; # endif return ret; } #endif OFSocketAddress OFSocketAddressParseIPv4(OFString *IPv4, uint16_t port) { void *pool = objc_autoreleasePoolPush(); OFCharacterSet *whitespaceCharacterSet = [OFCharacterSet whitespaceCharacterSet]; OFSocketAddress ret; struct sockaddr_in *addrIn = &ret.sockaddr.in; OFArray OF_GENERIC(OFString *) *components; uint32_t addr; memset(&ret, '\0', sizeof(ret)); ret.family = OFSocketAddressFamilyIPv4; #if defined(OF_WII) || defined(OF_NINTENDO_3DS) ret.length = 8; #else ret.length = sizeof(ret.sockaddr.in); #endif addrIn->sin_family = AF_INET; addrIn->sin_port = OFToBigEndian16(port); #ifdef OF_WII addrIn->sin_len = ret.length; #endif components = [IPv4 componentsSeparatedByString: @"."]; if (components.count != 4) @throw [OFInvalidFormatException exception]; addr = 0; for (OFString *component in components) { unsigned long long number; if (component.length == 0) @throw [OFInvalidFormatException exception]; if ([component indexOfCharacterFromSet: whitespaceCharacterSet] != OFNotFound) @throw [OFInvalidFormatException exception]; number = component.unsignedLongLongValue; if (number > UINT8_MAX) @throw [OFInvalidFormatException exception]; addr = (addr << 8) | ((uint32_t)number & 0xFF); } addrIn->sin_addr.s_addr = OFToBigEndian32(addr); objc_autoreleasePoolPop(pool); return ret; } static uint16_t parseIPv6Component(OFString *component) { unsigned long long number; if ([component indexOfCharacterFromSet: [OFCharacterSet whitespaceCharacterSet]] != OFNotFound) @throw [OFInvalidFormatException exception]; number = [component unsignedLongLongValueWithBase: 16]; if (number > UINT16_MAX) @throw [OFInvalidFormatException exception]; return (uint16_t)number; } OFSocketAddress OFSocketAddressParseIPv6(OFString *IPv6, uint16_t port) { void *pool = objc_autoreleasePoolPush(); OFSocketAddress ret; struct sockaddr_in6 *addrIn6 = &ret.sockaddr.in6; size_t doubleColon; memset(&ret, '\0', sizeof(ret)); ret.family = OFSocketAddressFamilyIPv6; ret.length = sizeof(ret.sockaddr.in6); #ifdef AF_INET6 addrIn6->sin6_family = AF_INET6; #else addrIn6->sin6_family = AF_UNSPEC; #endif addrIn6->sin6_port = OFToBigEndian16(port); doubleColon = [IPv6 rangeOfString: @"::"].location; if (doubleColon != OFNotFound) { OFString *left = [IPv6 substringToIndex: doubleColon]; OFString *right = [IPv6 substringFromIndex: doubleColon + 2]; OFArray OF_GENERIC(OFString *) *leftComponents; OFArray OF_GENERIC(OFString *) *rightComponents; size_t i; if ([right hasPrefix: @":"] || [right containsString: @"::"]) |
︙ | ︙ | |||
492 493 494 495 496 497 498 | } objc_autoreleasePoolPop(pool); return ret; } | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > > | | | | | > > > | > > > > > > > > > > > > > > < < | | | | | | | | | | | | | | | | | | | | > > > > > > > > > | | | < < < | | 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 | } objc_autoreleasePoolPop(pool); return ret; } OFSocketAddress OFSocketAddressParseIP(OFString *IP, uint16_t port) { OFSocketAddress ret; @try { ret = OFSocketAddressParseIPv6(IP, port); } @catch (OFInvalidFormatException *e) { ret = OFSocketAddressParseIPv4(IP, port); } return ret; } OFSocketAddress OFSocketAddressMakeIPX(const unsigned char node[IPX_NODE_LEN], uint32_t network, uint16_t port) { OFSocketAddress ret; memset(&ret, '\0', sizeof(ret)); ret.family = OFSocketAddressFamilyIPX; ret.length = sizeof(ret.sockaddr.ipx); #ifdef AF_IPX ret.sockaddr.ipx.sipx_family = AF_IPX; #else ret.sockaddr.ipx.sipx_family = AF_UNSPEC; #endif memcpy(ret.sockaddr.ipx.sipx_node, node, IPX_NODE_LEN); network = OFToBigEndian32(network); memcpy(&ret.sockaddr.ipx.sipx_network, &network, sizeof(ret.sockaddr.ipx.sipx_network)); ret.sockaddr.ipx.sipx_port = OFToBigEndian16(port); return ret; } OFSocketAddress OFSocketAddressMakeUNIX(OFString *path) { void *pool = objc_autoreleasePoolPush(); OFStringEncoding encoding = [OFLocale encoding]; size_t length = [path cStringLengthWithEncoding: encoding]; OFSocketAddress ret; if (length > sizeof(ret.sockaddr.un.sun_path)) @throw [OFOutOfRangeException exception]; memset(&ret, '\0', sizeof(ret)); ret.family = OFSocketAddressFamilyUNIX; ret.length = (socklen_t) (offsetof(struct sockaddr_un, sun_path) + length); #ifdef AF_UNIX ret.sockaddr.un.sun_family = AF_UNIX; #else ret.sockaddr.un.sun_family = AF_UNSPEC; #endif memcpy(ret.sockaddr.un.sun_path, [path cStringWithEncoding: encoding], length); objc_autoreleasePoolPop(pool); return ret; } bool OFSocketAddressEqual(const OFSocketAddress *address1, const OFSocketAddress *address2) { const struct sockaddr_in *addrIn1, *addrIn2; const struct sockaddr_in6 *addrIn6_1, *addrIn6_2; const struct sockaddr_ipx *addrIPX1, *addrIPX2; void *pool; OFString *path1, *path2; bool ret; if (address1->family != address2->family) return false; switch (address1->family) { case OFSocketAddressFamilyIPv4: #if defined(OF_WII) || defined(OF_NINTENDO_3DS) if (address1->length < 8 || address2->length < 8) @throw [OFInvalidArgumentException exception]; #else if (address1->length < (socklen_t)sizeof(struct sockaddr_in) || address2->length < (socklen_t)sizeof(struct sockaddr_in)) @throw [OFInvalidArgumentException exception]; #endif addrIn1 = &address1->sockaddr.in; addrIn2 = &address2->sockaddr.in; if (addrIn1->sin_port != addrIn2->sin_port) return false; if (addrIn1->sin_addr.s_addr != addrIn2->sin_addr.s_addr) return false; return true; case OFSocketAddressFamilyIPv6: if (address1->length < (socklen_t)sizeof(struct sockaddr_in6) || address2->length < (socklen_t)sizeof(struct sockaddr_in6)) @throw [OFInvalidArgumentException exception]; addrIn6_1 = &address1->sockaddr.in6; addrIn6_2 = &address2->sockaddr.in6; if (addrIn6_1->sin6_port != addrIn6_2->sin6_port) return false; if (memcmp(addrIn6_1->sin6_addr.s6_addr, addrIn6_2->sin6_addr.s6_addr, sizeof(addrIn6_1->sin6_addr.s6_addr)) != 0) return false; return true; case OFSocketAddressFamilyIPX: if (address1->length < (socklen_t)sizeof(struct sockaddr_ipx) || address2->length < (socklen_t)sizeof(struct sockaddr_ipx)) @throw [OFInvalidArgumentException exception]; addrIPX1 = &address1->sockaddr.ipx; addrIPX2 = &address2->sockaddr.ipx; if (addrIPX1->sipx_port != addrIPX2->sipx_port) return false; if (memcmp(&addrIPX1->sipx_network, &addrIPX2->sipx_network, 4) != 0) return false; if (memcmp(addrIPX1->sipx_node, addrIPX2->sipx_node, IPX_NODE_LEN) != 0) return false; return true; case OFSocketAddressFamilyUNIX: pool = objc_autoreleasePoolPush(); path1 = OFSocketAddressUNIXPath(address1); path2 = OFSocketAddressUNIXPath(address2); if (path1 == nil || path2 == nil) { objc_autoreleasePoolPop(pool); return false; } ret = [path1 isEqual: path2]; objc_autoreleasePoolPop(pool); return ret; default: @throw [OFInvalidArgumentException exception]; } } unsigned long OFSocketAddressHash(const OFSocketAddress *address) { unsigned long hash; OFHashInit(&hash); OFHashAdd(&hash, address->family); switch (address->family) { case OFSocketAddressFamilyIPv4: #if defined(OF_WII) || defined(OF_NINTENDO_3DS) if (address->length < 8) @throw [OFInvalidArgumentException exception]; #else if (address->length < (socklen_t)sizeof(struct sockaddr_in)) @throw [OFInvalidArgumentException exception]; #endif OFHashAdd(&hash, address->sockaddr.in.sin_port >> 8); OFHashAdd(&hash, address->sockaddr.in.sin_port); OFHashAdd(&hash, address->sockaddr.in.sin_addr.s_addr >> 24); OFHashAdd(&hash, address->sockaddr.in.sin_addr.s_addr >> 16); OFHashAdd(&hash, address->sockaddr.in.sin_addr.s_addr >> 8); OFHashAdd(&hash, address->sockaddr.in.sin_addr.s_addr); break; case OFSocketAddressFamilyIPv6: if (address->length < (socklen_t)sizeof(struct sockaddr_in6)) @throw [OFInvalidArgumentException exception]; OFHashAdd(&hash, address->sockaddr.in6.sin6_port >> 8); OFHashAdd(&hash, address->sockaddr.in6.sin6_port); for (size_t i = 0; i < sizeof(address->sockaddr.in6.sin6_addr.s6_addr); i++) OFHashAdd(&hash, address->sockaddr.in6.sin6_addr.s6_addr[i]); break; case OFSocketAddressFamilyIPX:; unsigned char network[ sizeof(address->sockaddr.ipx.sipx_network)]; if (address->length < (socklen_t)sizeof(struct sockaddr_ipx)) @throw [OFInvalidArgumentException exception]; OFHashAdd(&hash, address->sockaddr.ipx.sipx_port >> 8); OFHashAdd(&hash, address->sockaddr.ipx.sipx_port); memcpy(network, &address->sockaddr.ipx.sipx_network, sizeof(network)); for (size_t i = 0; i < sizeof(network); i++) OFHashAdd(&hash, network[i]); for (size_t i = 0; i < IPX_NODE_LEN; i++) OFHashAdd(&hash, address->sockaddr.ipx.sipx_node[i]); break; case OFSocketAddressFamilyUNIX:; void *pool = objc_autoreleasePoolPush(); OFString *path = OFSocketAddressUNIXPath(address); hash = path.hash; objc_autoreleasePoolPop(pool); return hash; default: @throw [OFInvalidArgumentException exception]; } OFHashFinalize(&hash); return hash; } static OFString * IPv4String(const OFSocketAddress *address) { const struct sockaddr_in *addrIn = &address->sockaddr.in; uint32_t addr = OFFromBigEndian32(addrIn->sin_addr.s_addr); OFString *string; string = [OFString stringWithFormat: @"%u.%u.%u.%u", (addr & 0xFF000000) >> 24, (addr & 0x00FF0000) >> 16, (addr & 0x0000FF00) >> 8, addr & 0x000000FF]; return string; } static OFString * IPv6String(const OFSocketAddress *address) { OFMutableString *string = [OFMutableString string]; const struct sockaddr_in6 *addrIn6 = &address->sockaddr.in6; int_fast8_t zerosStart = -1, maxZerosStart = -1; uint_fast8_t zerosCount = 0, maxZerosCount = 0; bool first = true; |
︙ | ︙ | |||
751 752 753 754 755 756 757 | addrIn6->sin6_addr.s6_addr[i + 1]]; first = false; } } [string makeImmutable]; | < < < | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > | 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 | addrIn6->sin6_addr.s6_addr[i + 1]]; first = false; } } [string makeImmutable]; return string; } OFString * OFSocketAddressString(const OFSocketAddress *address) { switch (address->family) { case OFSocketAddressFamilyIPv4: return IPv4String(address); case OFSocketAddressFamilyIPv6: return IPv6String(address); default: @throw [OFInvalidArgumentException exception]; } } void OFSocketAddressSetPort(OFSocketAddress *address, uint16_t port) { switch (address->family) { case OFSocketAddressFamilyIPv4: address->sockaddr.in.sin_port = OFToBigEndian16(port); break; case OFSocketAddressFamilyIPv6: address->sockaddr.in6.sin6_port = OFToBigEndian16(port); break; case OFSocketAddressFamilyIPX: address->sockaddr.ipx.sipx_port = OFToBigEndian16(port); break; default: @throw [OFInvalidArgumentException exception]; } } uint16_t OFSocketAddressPort(const OFSocketAddress *address) { switch (address->family) { case OFSocketAddressFamilyIPv4: return OFFromBigEndian16(address->sockaddr.in.sin_port); case OFSocketAddressFamilyIPv6: return OFFromBigEndian16(address->sockaddr.in6.sin6_port); case OFSocketAddressFamilyIPX: return OFFromBigEndian16(address->sockaddr.ipx.sipx_port); default: @throw [OFInvalidArgumentException exception]; } } void OFSocketAddressSetIPXNetwork(OFSocketAddress *address, uint32_t network) { if (address->family != OFSocketAddressFamilyIPX) @throw [OFInvalidArgumentException exception]; network = OFToBigEndian32(network); memcpy(&address->sockaddr.ipx.sipx_network, &network, sizeof(address->sockaddr.ipx.sipx_network)); } uint32_t OFSocketAddressIPXNetwork(const OFSocketAddress *address) { uint32_t network; if (address->family != OFSocketAddressFamilyIPX) @throw [OFInvalidArgumentException exception]; memcpy(&network, &address->sockaddr.ipx.sipx_network, sizeof(network)); return OFFromBigEndian32(network); } void OFSocketAddressSetIPXNode(OFSocketAddress *address, const unsigned char node[IPX_NODE_LEN]) { if (address->family != OFSocketAddressFamilyIPX) @throw [OFInvalidArgumentException exception]; memcpy(address->sockaddr.ipx.sipx_node, node, IPX_NODE_LEN); } void OFSocketAddressIPXNode(const OFSocketAddress *address, unsigned char node[IPX_NODE_LEN]) { if (address->family != OFSocketAddressFamilyIPX) @throw [OFInvalidArgumentException exception]; memcpy(node, address->sockaddr.ipx.sipx_node, IPX_NODE_LEN); } OFString * OFSocketAddressUNIXPath(const OFSocketAddress *_Nonnull address) { socklen_t length; if (address->family != OFSocketAddressFamilyUNIX) @throw [OFInvalidArgumentException exception]; length = address->length - offsetof(struct sockaddr_un, sun_path); for (socklen_t i = 0; i < length; i++) if (address->sockaddr.un.sun_path[i] == 0) length = i; if (length <= 0) return nil; return [OFString stringWithCString: address->sockaddr.un.sun_path encoding: [OFLocale encoding] length: length]; } |
Modified src/OFSortedList.h from [cd3a196397] to [3a5eb28c9b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
31 32 33 34 35 36 37 | #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif { OF_RESERVE_IVARS(OFSortedList, 4) } | | | | < | | < | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # define ObjectType id #endif { OF_RESERVE_IVARS(OFSortedList, 4) } - (OFListItem)appendObject: (ObjectType)object OF_UNAVAILABLE; - (OFListItem)prependObject: (ObjectType)object OF_UNAVAILABLE; - (OFListItem)insertObject: (ObjectType)object beforeListItem: (OFListItem)listItem OF_UNAVAILABLE; - (OFListItem)insertObject: (ObjectType)object afterListItem: (OFListItem)listItem OF_UNAVAILABLE; /** * @brief Inserts the object to the list while keeping the list sorted. * * @param object The object to insert * @return The list object for the object just added */ - (OFListItem)insertObject: (ObjectType <OFComparing>)object; #if !defined(OF_HAVE_GENERICS) && !defined(DOXYGEN) # undef ObjectType #endif @end OF_ASSUME_NONNULL_END |
Modified src/OFSortedList.m from [3644e3b345] to [8d1674288f].
1 | /* | < < | | | | < | < | | | > | > | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFSortedList.h" @implementation OFSortedList - (OFListItem)appendObject: (id)object { OF_UNRECOGNIZED_SELECTOR } - (OFListItem)prependObject: (id)object { OF_UNRECOGNIZED_SELECTOR } - (OFListItem)insertObject: (id)object beforeListItem: (OFListItem)listItem { OF_UNRECOGNIZED_SELECTOR } - (OFListItem)insertObject: (id)object afterListItem: (OFListItem)listItem { OF_UNRECOGNIZED_SELECTOR } - (OFListItem)insertObject: (id <OFComparing>)object { OFListItem iter; for (iter = _lastListItem; iter != NULL; iter = OFListItemPrevious(iter)) { if ([object compare: OFListItemObject(iter)] != OFOrderedAscending) return [super insertObject: object afterListItem: iter]; } return [super prependObject: object]; } @end |
Modified src/OFStdIOStream+Private.h from [c5d65c7b40] to [689e88ea63].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFStdIOStream.h from [a6d2486cab] to [fc2f501857].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | @class OFColor; /** * @class OFStdIOStream OFStdIOStream.h ObjFW/OFStdIOStream.h * * @brief A class for providing standard input, output and error as OFStream. * | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | @class OFColor; /** * @class OFStdIOStream OFStdIOStream.h ObjFW/OFStdIOStream.h * * @brief A class for providing standard input, output and error as OFStream. * * The global variables @ref OFStdIn, @ref OFStdOut and @ref OFStdErr are * instances of this class and need no initialization. */ #ifdef OF_STDIO_STREAM_WIN32_CONSOLE_H OF_SUBCLASSING_RESTRICTED #endif @interface OFStdIOStream: OFStream #if !defined(OF_WINDOWS) && !defined(OF_AMIGAOS) |
︙ | ︙ | |||
116 117 118 119 120 121 122 | /** * @brief Moves the cursor to the specified absolute position. Does nothing if * there is no underlying terminal. * * @param position The position to move the cursor to */ | | | | | | | | > > > > | > > > > > > > | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | /** * @brief Moves the cursor to the specified absolute position. Does nothing if * there is no underlying terminal. * * @param position The position to move the cursor to */ - (void)setCursorPosition: (OFPoint)position; /** * @brief Moves the cursor to the specified relative position. Does nothing if * there is no underlying terminal. * * @param position The position to move the cursor to */ - (void)setRelativeCursorPosition: (OFPoint)position; @end #ifdef __cplusplus extern "C" { #endif /** @file */ /** * @brief The standard input as an OFStream. */ extern OFStdIOStream *_Nullable OFStdIn; /** * @brief The standard output as an OFStream. */ extern OFStdIOStream *_Nullable OFStdOut; /** * @brief The standard error as an OFStream. */ extern OFStdIOStream *_Nullable OFStdErr; /** * @brief Logs the specified printf-style format to @ref OFStdErr. * * This prefixes the output with the date, timestamp, process name and PID. * * @param format The format for the line to log. See @ref OFStream#writeFormat:. */ extern void OFLog(OFConstantString *format, ...); /** * @brief Logs the specified printf-style format to @ref OFStdErr. * * This prefixes the output with the date, timestamp, process name and PID. * * @param format The format for the line to log. See @ref OFStream#writeFormat:. * @param arguments The arguments for the format */ extern void OFLogV(OFConstantString *format, va_list arguments); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFStdIOStream.m from [10bbd8e570] to [f006bf536d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
59 60 61 62 63 64 65 | void _reference_to_OFWin32ConsoleStdIOStream(void) { [OFWin32ConsoleStdIOStream class]; } #endif | | | | | | | | > > > > > > > > > > < < < | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | void _reference_to_OFWin32ConsoleStdIOStream(void) { [OFWin32ConsoleStdIOStream class]; } #endif OFStdIOStream *OFStdIn = nil; OFStdIOStream *OFStdOut = nil; OFStdIOStream *OFStdErr = nil; #ifdef OF_AMIGAOS OF_DESTRUCTOR() { [OFStdIn dealloc]; [OFStdOut dealloc]; [OFStdErr dealloc]; } #endif void OFLog(OFConstantString *format, ...) { va_list arguments; va_start(arguments, format); OFLogV(format, arguments); va_end(arguments); } void OFLogV(OFConstantString *format, va_list arguments) { void *pool = objc_autoreleasePoolPush(); OFDate *date; OFString *dateString, *me, *msg; date = [OFDate date]; dateString = [date localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; #ifdef OF_HAVE_FILES me = [OFApplication programName].lastPathComponent; #else me = [OFApplication programName]; #endif msg = [[[OFString alloc] initWithFormat: format arguments: arguments] autorelease]; [OFStdErr writeFormat: @"[%@.%03d %@(%d)] %@\n", dateString, date.microsecond / 1000, me, getpid(), msg]; objc_autoreleasePoolPop(pool); } #ifdef HAVE_ISATTY static int colorToANSI(OFColor *color) |
︙ | ︙ | |||
151 152 153 154 155 156 157 | if (self != [OFStdIOStream class]) return; # ifndef OF_AMIGAOS int fd; if ((fd = fileno(stdin)) >= 0) | < | | | | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | if (self != [OFStdIOStream class]) return; # ifndef OF_AMIGAOS int fd; if ((fd = fileno(stdin)) >= 0) OFStdIn = [[OFStdIOStream alloc] of_initWithFileDescriptor: fd]; if ((fd = fileno(stdout)) >= 0) OFStdOut = [[OFStdIOStream alloc] of_initWithFileDescriptor: fd]; if ((fd = fileno(stderr)) >= 0) OFStdErr = [[OFStdIOStream alloc] of_initWithFileDescriptor: fd]; # else BPTR input, output, error; bool inputClosable = false, outputClosable = false, errorClosable = false; input = Input(); |
︙ | ︙ | |||
183 184 185 186 187 188 189 | } if (error == 0) { error = Open("*", MODE_OLDFILE); errorClosable = true; } | | | | | | | | < | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | } if (error == 0) { error = Open("*", MODE_OLDFILE); errorClosable = true; } OFStdIn = [[OFStdIOStream alloc] of_initWithHandle: input closable: inputClosable]; OFStdOut = [[OFStdIOStream alloc] of_initWithHandle: output closable: outputClosable]; OFStdErr = [[OFStdIOStream alloc] of_initWithHandle: error closable: errorClosable]; # endif } #endif - (instancetype)init { OF_INVALID_INIT_METHOD } #ifndef OF_AMIGAOS - (instancetype)of_initWithFileDescriptor: (int)fd { self = [super init]; _fd = fd; return self; } #else - (instancetype)of_initWithHandle: (BPTR)handle closable: (bool)closable { self = [super init]; _handle = handle; _closable = closable; return self; |
︙ | ︙ | |||
244 245 246 247 248 249 250 | if (_handle == 0) #endif @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } | | < | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | if (_handle == 0) #endif @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { ssize_t ret; #ifndef OF_AMIGAOS if (_fd == -1) @throw [OFNotOpenException exceptionWithObject: self]; |
︙ | ︙ | |||
286 287 288 289 290 291 292 | if (ret == 0) _atEndOfStream = true; return ret; } | | < | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | if (ret == 0) _atEndOfStream = true; return ret; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { #ifndef OF_AMIGAOS if (_fd == -1) @throw [OFNotOpenException exceptionWithObject: self]; # ifndef OF_WINDOWS ssize_t bytesWritten; |
︙ | ︙ | |||
384 385 386 387 388 389 390 | - (void)release { } - (unsigned int)retainCount { | | | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | - (void)release { } - (unsigned int)retainCount { return OFMaxRetainCount; } - (bool)hasTerminal { #ifdef HAVE_ISATTY return isatty(_fd); #else |
︙ | ︙ | |||
494 495 496 497 498 499 500 | if (!isatty(_fd)) return; [self writeFormat: @"\033[%uG", column + 1]; #endif } | | | | 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 | if (!isatty(_fd)) return; [self writeFormat: @"\033[%uG", column + 1]; #endif } - (void)setCursorPosition: (OFPoint)position { if (position.x < 0 || position.y < 0) @throw [OFInvalidArgumentException exception]; #ifdef HAVE_ISATTY if (!isatty(_fd)) return; [self writeFormat: @"\033[%u;%uH", (unsigned)position.y + 1, (unsigned)position.x + 1]; #endif } - (void)setRelativeCursorPosition: (OFPoint)position { #ifdef HAVE_ISATTY if (!isatty(_fd)) return; if (position.x > 0) [self writeFormat: @"\033[%uC", (unsigned)position.x]; |
︙ | ︙ |
Renamed and modified src/of_strptime.h [569fe52fbb] to src/OFStrPTime.h [0432d594e4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | #import "macros.h" OF_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { #endif | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #import "macros.h" OF_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { #endif extern const char *_Nullable OFStrPTime(const char *buffer, const char *format, struct tm *tm, short *_Nullable tz); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Renamed and modified src/of_strptime.m [ef61304e79] to src/OFStrPTime.m [7afa230e7d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #include <string.h> #include <time.h> #import "macros.h" const char * | | | | | | | | < | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #include <string.h> #include <time.h> #import "macros.h" const char * OFStrPTime(const char *buffer, const char *format, struct tm *tm, short *tz) { enum { stateSearchConversionSpecifier, stateInConversionSpecifier } state = stateSearchConversionSpecifier; size_t j, bufferLen, formatLen; bufferLen = strlen(buffer); formatLen = strlen(format); j = 0; for (size_t i = 0; i < formatLen; i++) { if (j >= bufferLen) return NULL; switch (state) { case stateSearchConversionSpecifier: if (format[i] == '%') state = stateInConversionSpecifier; else if (format[i] != buffer[j++]) return NULL; break; case stateInConversionSpecifier:; int k, maxLen, number = 0; switch (format[i]) { case 'd': case 'e': case 'H': case 'm': |
︙ | ︙ | |||
219 220 221 222 223 224 225 | break; case 't': if (buffer[j++] != '\t') return NULL; break; } | | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | break; case 't': if (buffer[j++] != '\t') return NULL; break; } state = stateSearchConversionSpecifier; break; } } return buffer + j; } |
Modified src/OFStream+Private.h from [55a5b86424] to [571ecdcdc3].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFStream.h from [c1d35377bc] to [2b820d15bb].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
44 45 46 47 48 49 50 | * stream. * * @param length The length of the data that has been read * @param exception An exception which occurred while reading or `nil` on * success * @return A bool whether the same block should be used for the next read */ | < | | < | | < | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | * stream. * * @param length The length of the data that has been read * @param exception An exception which occurred while reading or `nil` on * success * @return A bool whether the same block should be used for the next read */ typedef bool (^OFStreamAsyncReadBlock)(size_t length, id _Nullable exception); /** * @brief A block which is called when a line was read asynchronously from a * stream. * * @param line The line which has been read or `nil` when the end of stream * occurred * @param exception An exception which occurred while reading or `nil` on * success * @return A bool whether the same block should be used for the next read */ typedef bool (^OFStreamAsyncReadLineBlock)(OFString *_Nullable line, id _Nullable exception); /** * @brief A block which is called when data was written asynchronously to a * stream. * * @param bytesWritten The number of bytes which have been written. This * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param exception An exception which occurred while writing or `nil` on * success * @return The data to repeat the write with or nil if it should not repeat */ typedef OFData *_Nullable (^OFStreamAsyncWriteDataBlock)(size_t bytesWritten, id _Nullable exception); /** * @brief A block which is called when a string was written asynchronously to a * stream. * * @param bytesWritten The number of bytes which have been written. This * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param exception An exception which occurred while writing or `nil` on * success * @return The string to repeat the write with or nil if it should not repeat */ typedef OFString *_Nullable (^OFStreamAsyncWriteStringBlock)( size_t bytesWritten, id _Nullable exception); #endif /** * @protocol OFStreamDelegate OFStream.h ObjFW/OFStream.h * * A delegate for OFStream. */ |
︙ | ︙ | |||
159 160 161 162 163 164 165 | * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param exception An exception that occurred while writing, or nil on success * @return The string to repeat the write with or nil if it should not repeat */ - (nullable OFString *)stream: (OFStream *)stream didWriteString: (OFString *)string | | | 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param exception An exception that occurred while writing, or nil on success * @return The string to repeat the write with or nil if it should not repeat */ - (nullable OFString *)stream: (OFStream *)stream didWriteString: (OFString *)string encoding: (OFStringEncoding)encoding bytesWritten: (size_t)bytesWritten exception: (nullable id)exception; @end /** * @class OFStream OFStream.h ObjFW/OFStream.h * |
︙ | ︙ | |||
206 207 208 209 210 211 212 | * @brief Whether the end of the stream has been reached. */ @property (readonly, nonatomic, getter=isAtEndOfStream) bool atEndOfStream; /** * @brief Whether writes are buffered. */ | | | 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | * @brief Whether the end of the stream has been reached. */ @property (readonly, nonatomic, getter=isAtEndOfStream) bool atEndOfStream; /** * @brief Whether writes are buffered. */ @property (nonatomic) bool buffersWrites; /** * @brief Whether data is present in the internal read buffer. */ @property (readonly, nonatomic) bool hasDataInReadBuffer; /** |
︙ | ︙ | |||
246 247 248 249 250 251 252 | * result of 0 bytes. * * @param buffer The buffer into which the data is read * @param length The length of the data that should be read at most. * The buffer *must* be *at least* this big! * @return The number of bytes read */ | | < | < | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | * result of 0 bytes. * * @param buffer The buffer into which the data is read * @param length The length of the data that should be read at most. * The buffer *must* be *at least* this big! * @return The number of bytes read */ - (size_t)readIntoBuffer: (void *)buffer length: (size_t)length; /** * @brief Reads exactly the specified length bytes from the stream into a * buffer. * * Unlike @ref readIntoBuffer:length:, this method does not return when less * than the specified length has been read - instead, it waits until it got * exactly the specified length. * * @warning Only call this when you know that specified amount of data is * available! Otherwise you will get an exception! * * @param buffer The buffer into which the data is read * @param length The length of the data that should be read. * The buffer *must* be *at least* this big! */ - (void)readIntoBuffer: (void *)buffer exactLength: (size_t)length; #ifdef OF_HAVE_SOCKETS /** * @brief Asynchronously reads *at most* size bytes from the stream into a * buffer. * * On network streams, this might read less than the specified number of bytes. |
︙ | ︙ | |||
288 289 290 291 292 293 294 | * for this to work! * * @param buffer The buffer into which the data is read. * The buffer must not be freed before the async read completed! * @param length The length of the data that should be read at most. * The buffer *must* be *at least* this big! */ | | < | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | * for this to work! * * @param buffer The buffer into which the data is read. * The buffer must not be freed before the async read completed! * @param length The length of the data that should be read at most. * The buffer *must* be *at least* this big! */ - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length; /** * @brief Asynchronously reads *at most* size bytes from the stream into a * buffer. * * On network streams, this might read less than the specified number of bytes. * If you want to read exactly the specified number of bytes, use |
︙ | ︙ | |||
314 315 316 317 318 319 320 | * The buffer must not be freed before the async read completed! * @param length The length of the data that should be read at most. * The buffer *must* be *at least* this big! * @param runLoopMode The run loop mode in which to perform the async read */ - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length | | | < | | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | * The buffer must not be freed before the async read completed! * @param length The length of the data that should be read at most. * The buffer *must* be *at least* this big! * @param runLoopMode The run loop mode in which to perform the async read */ - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode; /** * @brief Asynchronously reads exactly the specified length bytes from the * stream into a buffer. * * Unlike @ref asyncReadIntoBuffer:length:, this method does not call the * method when less than the specified length has been read - instead, it waits * until it got exactly the specified length, the stream has ended or an * exception occurred. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! * * @param buffer The buffer into which the data is read * @param length The length of the data that should be read. * The buffer *must* be *at least* this big! */ - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length; /** * @brief Asynchronously reads exactly the specified length bytes from the * stream into a buffer. * * Unlike @ref asyncReadIntoBuffer:length:, this method does not call the * method when less than the specified length has been read - instead, it waits * until it got exactly the specified length, the stream has ended or an * exception occurred. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! * * @param buffer The buffer into which the data is read * @param length The length of the data that should be read. * The buffer *must* be *at least* this big! * @param runLoopMode The run loop mode in which to perform the async read */ - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode; # ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously reads *at most* ref size bytes from the stream into a * buffer. * * On network streams, this might read less than the specified number of bytes. |
︙ | ︙ | |||
384 385 386 387 388 389 390 | * If the block returns true, it will be called again with the same * buffer and maximum length when more data has been received. If * you want the next block in the queue to handle the data * received next, you need to return false from the block. */ - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 | * If the block returns true, it will be called again with the same * buffer and maximum length when more data has been received. If * you want the next block in the queue to handle the data * received next, you need to return false from the block. */ - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length block: (OFStreamAsyncReadBlock)block; /** * @brief Asynchronously reads *at most* ref size bytes from the stream into a * buffer. * * On network streams, this might read less than the specified number of bytes. * If you want to read exactly the specified number of bytes, use |
︙ | ︙ | |||
414 415 416 417 418 419 420 | * If the block returns true, it will be called again with the same * buffer and maximum length when more data has been received. If * you want the next block in the queue to handle the data * received next, you need to return false from the block. */ - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length | | | | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | * If the block returns true, it will be called again with the same * buffer and maximum length when more data has been received. If * you want the next block in the queue to handle the data * received next, you need to return false from the block. */ - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamAsyncReadBlock)block; /** * @brief Asynchronously reads exactly the specified length bytes from the * stream into a buffer. * * Unlike @ref asyncReadIntoBuffer:length:block:, this method does not invoke * the block when less than the specified length has been read - instead, it |
︙ | ︙ | |||
440 441 442 443 444 445 446 | * If the block returns true, it will be called again with the same * buffer and exact length when more data has been received. If * you want the next block in the queue to handle the data * received next, you need to return false from the block. */ - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length | | | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | * If the block returns true, it will be called again with the same * buffer and exact length when more data has been received. If * you want the next block in the queue to handle the data * received next, you need to return false from the block. */ - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length block: (OFStreamAsyncReadBlock)block; /** * @brief Asynchronously reads exactly the specified length bytes from the * stream into a buffer. * * Unlike @ref asyncReadIntoBuffer:length:block:, this method does not invoke * the block when less than the specified length has been read - instead, it |
︙ | ︙ | |||
466 467 468 469 470 471 472 | * If the block returns true, it will be called again with the same * buffer and exact length when more data has been received. If * you want the next block in the queue to handle the data * received next, you need to return false from the block. */ - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length | | | | 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | * If the block returns true, it will be called again with the same * buffer and exact length when more data has been received. If * you want the next block in the queue to handle the data * received next, you need to return false from the block. */ - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamAsyncReadBlock)block; # endif #endif /** * @brief Reads a uint8_t from the stream. * * @warning Only call this when you know that enough data is available! |
︙ | ︙ | |||
531 532 533 534 535 536 537 | * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A double from the stream in the native endianess */ - (double)readBigEndianDouble; | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 522 523 524 525 526 527 528 529 530 531 532 533 534 535 | * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A double from the stream in the native endianess */ - (double)readBigEndianDouble; /** * @brief Reads a uint16_t from the stream which is encoded in little endian. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A uint16_t from the stream in native endianess |
︙ | ︙ | |||
656 657 658 659 660 661 662 | * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A double from the stream in the native endianess */ - (double)readLittleEndianDouble; | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 572 573 574 575 576 577 578 579 580 581 582 583 584 585 | * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @return A double from the stream in the native endianess */ - (double)readLittleEndianDouble; /** * @brief Reads the specified number of items with an item size of 1 from the * stream and returns them as OFData. * * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * |
︙ | ︙ | |||
754 755 756 757 758 759 760 | * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @param itemSize The size of each item * @param count The number of items to read * @return OFData with count items. */ | | < | 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 | * @warning Only call this when you know that enough data is available! * Otherwise you will get an exception! * * @param itemSize The size of each item * @param count The number of items to read * @return OFData with count items. */ - (OFData *)readDataWithItemSize: (size_t)itemSize count: (size_t)count; /** * @brief Returns OFData with all the remaining data of the stream. * * @return OFData with an item size of 1 with all the data of the stream until * the end of the stream is reached. */ |
︙ | ︙ | |||
797 798 799 800 801 802 803 | * Otherwise you will get an exception! * * @param encoding The encoding of the string to read from the stream * @param length The length (in bytes) of the string to read from the stream * @return A string with the specified length */ - (OFString *)readStringWithLength: (size_t)length | | | | | | | | | | | | | 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 | * Otherwise you will get an exception! * * @param encoding The encoding of the string to read from the stream * @param length The length (in bytes) of the string to read from the stream * @return A string with the specified length */ - (OFString *)readStringWithLength: (size_t)length encoding: (OFStringEncoding)encoding; /** * @brief Reads until a newline, `\0` or end of stream occurs. * * @return The line that was read, autoreleased, or `nil` if the end of the * stream has been reached. */ - (nullable OFString *)readLine; /** * @brief Reads with the specified encoding until a newline, `\0` or end of * stream occurs. * * @param encoding The encoding used by the stream * @return The line that was read, autoreleased, or `nil` if the end of the * stream has been reached. */ - (nullable OFString *)readLineWithEncoding: (OFStringEncoding)encoding; #ifdef OF_HAVE_SOCKETS /** * @brief Asynchronously reads until a newline, `\0`, end of stream or an * exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! */ - (void)asyncReadLine; /** * @brief Asynchronously reads with the specified encoding until a newline, * `\0`, end of stream or an exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! * * @param encoding The encoding used by the stream */ - (void)asyncReadLineWithEncoding: (OFStringEncoding)encoding; /** * @brief Asynchronously reads with the specified encoding until a newline, * `\0`, end of stream or an exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! * * @param encoding The encoding used by the stream * @param runLoopMode The run loop mode in which to perform the async read */ - (void)asyncReadLineWithEncoding: (OFStringEncoding)encoding runLoopMode: (OFRunLoopMode)runLoopMode; # ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously reads until a newline, `\0`, end of stream or an * exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! * * @param block The block to call when the data has been received. * If the block returns true, it will be called again when the next * line has been received. If you want the next block in the queue * to handle the next line, you need to return false from the * block. */ - (void)asyncReadLineWithBlock: (OFStreamAsyncReadLineBlock)block; /** * @brief Asynchronously reads with the specified encoding until a newline, * `\0`, end of stream or an exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! * * @param encoding The encoding used by the stream * @param block The block to call when the data has been received. * If the block returns true, it will be called again when the next * line has been received. If you want the next block in the queue * to handle the next line, you need to return false from the * block. */ - (void)asyncReadLineWithEncoding: (OFStringEncoding)encoding block: (OFStreamAsyncReadLineBlock)block; /** * @brief Asynchronously reads with the specified encoding until a newline, * `\0`, end of stream or an exception occurs. * * @note The stream must conform to @ref OFReadyForReadingObserving in order * for this to work! * * @param encoding The encoding used by the stream * @param runLoopMode The run loop mode in which to perform the async read * @param block The block to call when the data has been received. * If the block returns true, it will be called again when the next * line has been received. If you want the next block in the queue * to handle the next line, you need to return false from the * block. */ - (void)asyncReadLineWithEncoding: (OFStringEncoding)encoding runLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamAsyncReadLineBlock)block; # endif #endif /** * @brief Tries to read a line from the stream (see @ref readLine) and returns * `nil` if no complete line has been received yet. * |
︙ | ︙ | |||
923 924 925 926 927 928 929 | * @ref readLineWithEncoding:) and returns `nil` if no complete line has * been received yet. * * @param encoding The encoding used by the stream * @return The line that was read, autoreleased, or `nil` if the line is not * complete yet */ | | | 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 | * @ref readLineWithEncoding:) and returns `nil` if no complete line has * been received yet. * * @param encoding The encoding used by the stream * @return The line that was read, autoreleased, or `nil` if the line is not * complete yet */ - (nullable OFString *)tryReadLineWithEncoding: (OFStringEncoding)encoding; /** * @brief Reads until the specified string or `\0` is found or the end of * stream occurs. * * @param delimiter The delimiter * @return The line that was read, autoreleased, or `nil` if the end of the |
︙ | ︙ | |||
945 946 947 948 949 950 951 | * * @param delimiter The delimiter * @param encoding The encoding used by the stream * @return The line that was read, autoreleased, or `nil` if the end of the * stream has been reached. */ - (nullable OFString *)readTillDelimiter: (OFString *)delimiter | | | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 | * * @param delimiter The delimiter * @param encoding The encoding used by the stream * @return The line that was read, autoreleased, or `nil` if the end of the * stream has been reached. */ - (nullable OFString *)readTillDelimiter: (OFString *)delimiter encoding: (OFStringEncoding)encoding; /** * @brief Tries to reads until the specified string or `\0` is found or the end * of stream (see @ref readTillDelimiter:) and returns `nil` if not * enough data has been received yet. * * @param delimiter The delimiter |
︙ | ︙ | |||
969 970 971 972 973 974 975 | * * @param delimiter The delimiter * @param encoding The encoding used by the stream * @return The line that was read, autoreleased, or `nil` if the end of the * stream has been reached. */ - (nullable OFString *)tryReadTillDelimiter: (OFString *)delimiter | | > > > > | > > > > > > > < < | < | 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 | * * @param delimiter The delimiter * @param encoding The encoding used by the stream * @return The line that was read, autoreleased, or `nil` if the end of the * stream has been reached. */ - (nullable OFString *)tryReadTillDelimiter: (OFString *)delimiter encoding: (OFStringEncoding)encoding; /** * @brief Writes everything in the write buffer to the stream. * * @return Whether the write buffer was flushed entirely. On non-blocking * sockets, this can return `false` if flushing the write buffer in its * entirety would block. */ - (bool)flushWriteBuffer; /** * @brief Writes from a buffer into the stream. * * In non-blocking mode, if less than the specified length could be written, an * @ref OFWriteFailedException is thrown with @ref OFWriteFailedException#errNo * being set to `EWOULDBLOCK` or `EAGAIN` (you need to check for both, as they * are not the same on some systems) and * @ref OFWriteFailedException#bytesWritten being set to the number of bytes * that were written, if any. * * @param buffer The buffer from which the data is written into the stream * @param length The length of the data that should be written */ - (void)writeBuffer: (const void *)buffer length: (size_t)length; #ifdef OF_HAVE_SOCKETS /** * @brief Asynchronously writes data into the stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! |
︙ | ︙ | |||
1008 1009 1010 1011 1012 1013 1014 | * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * * @param data The data which is written into the stream * @param runLoopMode The run loop mode in which to perform the async write */ - (void)asyncWriteData: (OFData *)data | | | 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 | * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * * @param data The data which is written into the stream * @param runLoopMode The run loop mode in which to perform the async write */ - (void)asyncWriteData: (OFData *)data runLoopMode: (OFRunLoopMode)runLoopMode; /** * @brief Asynchronously writes a string in UTF-8 encoding into the stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * |
︙ | ︙ | |||
1032 1033 1034 1035 1036 1037 1038 | * for this to work! * * @param string The string which is written into the stream * @param encoding The encoding in which the string should be written to the * stream */ - (void)asyncWriteString: (OFString *)string | | | | | | | | | | | | | > > > > > > > > > > > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < | < < < < < < < < < < < < < < > > > > > > > > < < < < < < < < < < | < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | > > < | > > < | < > > < | > > < | < | | > > < | | | > > < | < | 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 | * for this to work! * * @param string The string which is written into the stream * @param encoding The encoding in which the string should be written to the * stream */ - (void)asyncWriteString: (OFString *)string encoding: (OFStringEncoding)encoding; /** * @brief Asynchronously writes a string in the specified encoding into the * stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * * @param string The string which is written into the stream * @param encoding The encoding in which the string should be written to the * stream * @param runLoopMode The run loop mode in which to perform the async write */ - (void)asyncWriteString: (OFString *)string encoding: (OFStringEncoding)encoding runLoopMode: (OFRunLoopMode)runLoopMode; # ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously writes data into the stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * * @param data The data which is written into the stream * @param block The block to call when the data has been written. It should * return the data for the next write with the same callback or * nil if it should not repeat. */ - (void)asyncWriteData: (OFData *)data block: (OFStreamAsyncWriteDataBlock)block; /** * @brief Asynchronously writes data into the stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * * @param data The data which is written into the stream * @param runLoopMode The run loop mode in which to perform the async write * @param block The block to call when the data has been written. It should * return the data for the next write with the same callback or * nil if it should not repeat. */ - (void)asyncWriteData: (OFData *)data runLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamAsyncWriteDataBlock)block; /** * @brief Asynchronously writes a string into the stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * * @param string The string which is written into the stream * @param block The block to call when the string has been written. It should * return the string for the next write with the same callback or * nil if it should not repeat. */ - (void)asyncWriteString: (OFString *)string block: (OFStreamAsyncWriteStringBlock)block; /** * @brief Asynchronously writes a string in the specified encoding into the * stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * * @param string The string which is written into the stream * @param encoding The encoding in which the string should be written to the * stream * @param block The block to call when the string has been written. It should * return the string for the next write with the same callback or * nil if it should not repeat. */ - (void)asyncWriteString: (OFString *)string encoding: (OFStringEncoding)encoding block: (OFStreamAsyncWriteStringBlock)block; /** * @brief Asynchronously writes a string in the specified encoding into the * stream. * * @note The stream must conform to @ref OFReadyForWritingObserving in order * for this to work! * * @param string The string which is written into the stream * @param encoding The encoding in which the string should be written to the * stream * @param runLoopMode The run loop mode in which to perform the async write * @param block The block to call when the string has been written. It should * return the string for the next write with the same callback or * nil if it should not repeat. */ - (void)asyncWriteString: (OFString *)string encoding: (OFStringEncoding)encoding runLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamAsyncWriteStringBlock)block; # endif #endif /** * @brief Writes a uint8_t into the stream. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param int8 A uint8_t */ - (void)writeInt8: (uint8_t)int8; /** * @brief Writes a uint16_t into the stream, encoded in big endian. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param int16 A uint16_t */ - (void)writeBigEndianInt16: (uint16_t)int16; /** * @brief Writes a uint32_t into the stream, encoded in big endian. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param int32 A uint32_t */ - (void)writeBigEndianInt32: (uint32_t)int32; /** * @brief Writes a uint64_t into the stream, encoded in big endian. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param int64 A uint64_t */ - (void)writeBigEndianInt64: (uint64_t)int64; /** * @brief Writes a float into the stream, encoded in big endian. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param float_ A float */ - (void)writeBigEndianFloat: (float)float_; /** * @brief Writes a double into the stream, encoded in big endian. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param double_ A double */ - (void)writeBigEndianDouble: (double)double_; /** * @brief Writes a uint16_t into the stream, encoded in little endian. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param int16 A uint16_t */ - (void)writeLittleEndianInt16: (uint16_t)int16; /** * @brief Writes a uint32_t into the stream, encoded in little endian. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param int32 A uint32_t */ - (void)writeLittleEndianInt32: (uint32_t)int32; /** * @brief Writes a uint64_t into the stream, encoded in little endian. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param int64 A uint64_t */ - (void)writeLittleEndianInt64: (uint64_t)int64; /** * @brief Writes a float into the stream, encoded in little endian. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param float_ A float */ - (void)writeLittleEndianFloat: (float)float_; /** * @brief Writes a double into the stream, encoded in little endian. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param double_ A double */ - (void)writeLittleEndianDouble: (double)double_; /** * @brief Writes OFData into the stream. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param data The OFData to write into the stream */ - (void)writeData: (OFData *)data; /** * @brief Writes a string into the stream, without the trailing zero. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param string The string from which the data is written to the stream */ - (void)writeString: (OFString *)string; /** * @brief Writes a string into the stream in the specified encoding, without * the trailing zero. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param string The string from which the data is written to the stream * @param encoding The encoding in which to write the string to the stream */ - (void)writeString: (OFString *)string encoding: (OFStringEncoding)encoding; /** * @brief Writes a string into the stream with a trailing newline. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param string The string from which the data is written to the stream */ - (void)writeLine: (OFString *)string; /** * @brief Writes a string into the stream in the specified encoding with a * trailing newline. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param string The string from which the data is written to the stream * @param encoding The encoding in which to write the string to the stream */ - (void)writeLine: (OFString *)string encoding: (OFStringEncoding)encoding; /** * @brief Writes a formatted string into the stream. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `OFUnichar` and `%S` for * `const OFUnichar *`. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param format A string used as format */ - (void)writeFormat: (OFConstantString *)format, ...; /** * @brief Writes a formatted string into the stream. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `OFUnichar` and `%S` for * `const OFUnichar *`. * * In non-blocking mode, the behavior is the same as @ref writeBuffer:length:. * * @param format A string used as format * @param arguments The arguments used in the format string */ - (void)writeFormat: (OFConstantString *)format arguments: (va_list)arguments; #ifdef OF_HAVE_SOCKETS /** * @brief Cancels all pending asynchronous requests on the stream. */ - (void)cancelAsyncRequests; #endif |
︙ | ︙ | |||
1432 1433 1434 1435 1436 1437 1438 | * * If the stream is seekable, a seek operation will discard any data which was * unread. * * @param buffer The buffer to unread * @param length The length of the buffer to unread */ | | < | < | < | 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 | * * If the stream is seekable, a seek operation will discard any data which was * unread. * * @param buffer The buffer to unread * @param length The length of the buffer to unread */ - (void)unreadFromBuffer: (const void *)buffer length: (size_t)length; /** * @brief Closes the stream. * * @note If you override this, make sure to call `[super close]`! */ - (void)close; /** * @brief Performs a lowlevel read. * * @warning Do not call this directly! * * @note Override this method with your actual read implementation when * subclassing! * * @param buffer The buffer for the data to read * @param length The length of the buffer * @return The number of bytes read */ - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length; /** * @brief Performs a lowlevel write. * * @warning Do not call this directly! * * @note Override this method with your actual write implementation when * subclassing! * * @param buffer The buffer with the data to write * @param length The length of the data to write * @return The number of bytes written */ - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length; /** * @brief Returns whether the lowlevel is at the end of the stream. * * @warning Do not call this directly! * * @note Override this method with your actual end of stream checking |
︙ | ︙ |
Modified src/OFStream.m from [b34f9f0d7d] to [7df47f7053].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
26 27 28 29 30 31 32 | #include <stdlib.h> #include <string.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif | < < < < > > > > < | < | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #include <stdlib.h> #include <string.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #include "platform.h" #if !defined(OF_WINDOWS) && !defined(OF_MORPHOS) # include <signal.h> #endif #import "OFStream.h" #import "OFStream+Private.h" #import "OFASPrintF.h" #import "OFData.h" #import "OFKernelEventObserver.h" #import "OFRunLoop+Private.h" #import "OFRunLoop.h" #ifdef OF_HAVE_SOCKETS # import "OFSocket+Private.h" #endif #import "OFString.h" #import "OFSystemInfo.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFSetOptionFailedException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" #define minReadSize 512 @implementation OFStream @synthesize buffersWrites = _buffersWrites; @synthesize of_waitingForDelimiter = _waitingForDelimiter, delegate = _delegate; #if defined(SIGPIPE) && defined(SIG_IGN) + (void)initialize |
︙ | ︙ | |||
88 89 90 91 92 93 94 95 96 97 98 99 100 | } @catch (id e) { [self release]; @throw e; } return self; } - (bool)lowlevelIsAtEndOfStream { OF_UNRECOGNIZED_SELECTOR } | > > > > > > > > | < | < | < | | | < | < | > | < | | < | < | | | < | | | | | | | | | | < | < < < | < | < < | < | < < | < | < < | < | < < | < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | < < | < | < < | < | < < | < | < < | < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | < | | < < < > | | | < | < | < | < | | | | < < | < | | | | | | > > | | | < < < < | | | < | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 | } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { OFFreeMemory(_readBufferMemory); OFFreeMemory(_writeBuffer); [super dealloc]; } - (bool)lowlevelIsAtEndOfStream { OF_UNRECOGNIZED_SELECTOR } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { OF_UNRECOGNIZED_SELECTOR } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { OF_UNRECOGNIZED_SELECTOR } - (id)copy { return [self retain]; } - (bool)isAtEndOfStream { if (_readBufferLength > 0) return false; return [self lowlevelIsAtEndOfStream]; } - (size_t)readIntoBuffer: (void *)buffer length: (size_t)length { if (_readBufferLength == 0) { /* * For small sizes, it is cheaper to read more and cache the * remainder - even if that means more copying of data - than * to do a syscall for every read. */ if (length < minReadSize) { char tmp[minReadSize], *readBuffer; size_t bytesRead; bytesRead = [self lowlevelReadIntoBuffer: tmp length: minReadSize]; if (bytesRead > length) { memcpy(buffer, tmp, length); readBuffer = OFAllocMemory(bytesRead - length, 1); memcpy(readBuffer, tmp + length, bytesRead - length); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength = bytesRead - length; return length; } else { memcpy(buffer, tmp, bytesRead); return bytesRead; } } return [self lowlevelReadIntoBuffer: buffer length: length]; } if (length >= _readBufferLength) { size_t ret = _readBufferLength; memcpy(buffer, _readBuffer, _readBufferLength); OFFreeMemory(_readBufferMemory); _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; return ret; } else { memcpy(buffer, _readBuffer, length); _readBuffer += length; _readBufferLength -= length; return length; } } - (void)readIntoBuffer: (void *)buffer exactLength: (size_t)length { size_t readLength = 0; while (readLength < length) { if (self.atEndOfStream) @throw [OFTruncatedDataException exception]; readLength += [self readIntoBuffer: (char *)buffer + readLength length: length - readLength]; } } #ifdef OF_HAVE_SOCKETS - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length { [self asyncReadIntoBuffer: buffer length: length runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode { OFStream <OFReadyForReadingObserving> *stream = (OFStream <OFReadyForReadingObserving> *)self; [OFRunLoop of_addAsyncReadForStream: stream buffer: buffer length: length mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length { [self asyncReadIntoBuffer: buffer exactLength: length runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode { OFStream <OFReadyForReadingObserving> *stream = (OFStream <OFReadyForReadingObserving> *)self; [OFRunLoop of_addAsyncReadForStream: stream buffer: buffer exactLength: length mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } # ifdef OF_HAVE_BLOCKS - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length block: (OFStreamAsyncReadBlock)block { [self asyncReadIntoBuffer: buffer length: length runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamAsyncReadBlock)block { OFStream <OFReadyForReadingObserving> *stream = (OFStream <OFReadyForReadingObserving> *)self; [OFRunLoop of_addAsyncReadForStream: stream buffer: buffer length: length mode: runLoopMode block: block delegate: nil]; } - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length block: (OFStreamAsyncReadBlock)block { [self asyncReadIntoBuffer: buffer exactLength: length runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length runLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamAsyncReadBlock)block { OFStream <OFReadyForReadingObserving> *stream = (OFStream <OFReadyForReadingObserving> *)self; [OFRunLoop of_addAsyncReadForStream: stream buffer: buffer exactLength: length mode: runLoopMode block: block delegate: nil]; } # endif #endif - (uint8_t)readInt8 { uint8_t ret; [self readIntoBuffer: (char *)&ret exactLength: 1]; return ret; } - (uint16_t)readBigEndianInt16 { uint16_t ret; [self readIntoBuffer: (char *)&ret exactLength: 2]; return OFFromBigEndian16(ret); } - (uint32_t)readBigEndianInt32 { uint32_t ret; [self readIntoBuffer: (char *)&ret exactLength: 4]; return OFFromBigEndian32(ret); } - (uint64_t)readBigEndianInt64 { uint64_t ret; [self readIntoBuffer: (char *)&ret exactLength: 8]; return OFFromBigEndian64(ret); } - (float)readBigEndianFloat { float ret; [self readIntoBuffer: (char *)&ret exactLength: 4]; return OFFromBigEndianFloat(ret); } - (double)readBigEndianDouble { double ret; [self readIntoBuffer: (char *)&ret exactLength: 8]; return OFFromBigEndianDouble(ret); } - (uint16_t)readLittleEndianInt16 { uint16_t ret; [self readIntoBuffer: (char *)&ret exactLength: 2]; return OFFromLittleEndian16(ret); } - (uint32_t)readLittleEndianInt32 { uint32_t ret; [self readIntoBuffer: (char *)&ret exactLength: 4]; return OFFromLittleEndian32(ret); } - (uint64_t)readLittleEndianInt64 { uint64_t ret; [self readIntoBuffer: (char *)&ret exactLength: 8]; return OFFromLittleEndian64(ret); } - (float)readLittleEndianFloat { float ret; [self readIntoBuffer: (char *)&ret exactLength: 4]; return OFFromLittleEndianFloat(ret); } - (double)readLittleEndianDouble { double ret; [self readIntoBuffer: (char *)&ret exactLength: 8]; return OFFromLittleEndianDouble(ret); } - (OFData *)readDataWithCount: (size_t)count { return [self readDataWithItemSize: 1 count: count]; } - (OFData *)readDataWithItemSize: (size_t)itemSize count: (size_t)count { OFData *ret; char *buffer; if OF_UNLIKELY (count > SIZE_MAX / itemSize) @throw [OFOutOfRangeException exception]; buffer = OFAllocMemory(count, itemSize); @try { [self readIntoBuffer: buffer exactLength: count * itemSize]; ret = [OFData dataWithItemsNoCopy: buffer count: count itemSize: itemSize freeWhenDone: true]; } @catch (id e) { OFFreeMemory(buffer); @throw e; } return ret; } - (OFData *)readDataUntilEndOfStream { OFMutableData *data = [OFMutableData data]; size_t pageSize = [OFSystemInfo pageSize]; char *buffer = OFAllocMemory(1, pageSize); @try { while (!self.atEndOfStream) { size_t length = [self readIntoBuffer: buffer length: pageSize]; [data addItems: buffer count: length]; } } @finally { OFFreeMemory(buffer); } [data makeImmutable]; return data; } - (OFString *)readStringWithLength: (size_t)length { return [self readStringWithLength: length encoding: OFStringEncodingUTF8]; } - (OFString *)readStringWithLength: (size_t)length encoding: (OFStringEncoding)encoding { OFString *ret; char *buffer = OFAllocMemory(length + 1, 1); buffer[length] = 0; @try { [self readIntoBuffer: buffer exactLength: length]; ret = [OFString stringWithCString: buffer encoding: encoding]; } @finally { OFFreeMemory(buffer); } return ret; } - (OFString *)tryReadLineWithEncoding: (OFStringEncoding)encoding { size_t pageSize, bufferLength; char *buffer, *readBuffer; OFString *ret; /* Look if there's a line or \0 in our buffer */ if (!_waitingForDelimiter && _readBuffer != NULL) { for (size_t i = 0; i < _readBufferLength; i++) { if OF_UNLIKELY (_readBuffer[i] == '\n' || _readBuffer[i] == '\0') { size_t retLength = i; if (i > 0 && _readBuffer[i - 1] == '\r') retLength--; ret = [OFString stringWithCString: _readBuffer encoding: encoding length: retLength]; _readBuffer += i + 1; _readBufferLength -= i + 1; _waitingForDelimiter = false; return ret; } } } /* Read and see if we got a newline or \0 */ pageSize = [OFSystemInfo pageSize]; buffer = OFAllocMemory(1, pageSize); @try { if ([self lowlevelIsAtEndOfStream]) { size_t retLength; if (_readBuffer == NULL) { _waitingForDelimiter = false; return nil; } retLength = _readBufferLength; if (retLength > 0 && _readBuffer[retLength - 1] == '\r') retLength--; ret = [OFString stringWithCString: _readBuffer encoding: encoding length: retLength]; OFFreeMemory(_readBufferMemory); _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; _waitingForDelimiter = false; return ret; } bufferLength = [self lowlevelReadIntoBuffer: buffer length: pageSize]; /* Look if there's a newline or \0 */ for (size_t i = 0; i < bufferLength; i++) { if OF_UNLIKELY (buffer[i] == '\n' || buffer[i] == '\0') { size_t retLength = _readBufferLength + i; char *retCString = OFAllocMemory(retLength, 1); if (_readBuffer != NULL) memcpy(retCString, _readBuffer, _readBufferLength); memcpy(retCString + _readBufferLength, buffer, i); if (retLength > 0 && retCString[retLength - 1] == '\r') retLength--; @try { ret = [OFString stringWithCString: retCString encoding: encoding length: retLength]; } @catch (id e) { if (bufferLength > 0) { /* * Append data to _readBuffer * to prevent loss of data. */ readBuffer = OFAllocMemory( _readBufferLength + bufferLength, 1); memcpy(readBuffer, _readBuffer, _readBufferLength); memcpy(readBuffer + _readBufferLength, buffer, bufferLength); OFFreeMemory(_readBufferMemory); _readBuffer = readBuffer; _readBufferMemory = readBuffer; _readBufferLength += bufferLength; } @throw e; } @finally { OFFreeMemory(retCString); } readBuffer = OFAllocMemory(bufferLength - i - 1, 1); if (readBuffer != NULL) memcpy(readBuffer, buffer + i + 1, bufferLength - i - 1); OFFreeMemory(_readBufferMemory); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength = bufferLength - i - 1; _waitingForDelimiter = false; return ret; } } /* There was no newline or \0 */ if (bufferLength > 0) { readBuffer = OFAllocMemory( _readBufferLength + bufferLength, 1); memcpy(readBuffer, _readBuffer, _readBufferLength); memcpy(readBuffer + _readBufferLength, buffer, bufferLength); OFFreeMemory(_readBufferMemory); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength += bufferLength; } } @finally { OFFreeMemory(buffer); } _waitingForDelimiter = true; return nil; } - (OFString *)readLine { return [self readLineWithEncoding: OFStringEncodingUTF8]; } - (OFString *)readLineWithEncoding: (OFStringEncoding)encoding { OFString *line = nil; while ((line = [self tryReadLineWithEncoding: encoding]) == nil) if (self.atEndOfStream) return nil; return line; } #ifdef OF_HAVE_SOCKETS - (void)asyncReadLine { [self asyncReadLineWithEncoding: OFStringEncodingUTF8 runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncReadLineWithEncoding: (OFStringEncoding)encoding { [self asyncReadLineWithEncoding: encoding runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncReadLineWithEncoding: (OFStringEncoding)encoding runLoopMode: (OFRunLoopMode)runLoopMode { OFStream <OFReadyForReadingObserving> *stream = (OFStream <OFReadyForReadingObserving> *)self; [OFRunLoop of_addAsyncReadLineForStream: stream encoding: encoding mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } # ifdef OF_HAVE_BLOCKS - (void)asyncReadLineWithBlock: (OFStreamAsyncReadLineBlock)block { [self asyncReadLineWithEncoding: OFStringEncodingUTF8 runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncReadLineWithEncoding: (OFStringEncoding)encoding block: (OFStreamAsyncReadLineBlock)block { [self asyncReadLineWithEncoding: encoding runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncReadLineWithEncoding: (OFStringEncoding)encoding runLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamAsyncReadLineBlock)block { OFStream <OFReadyForReadingObserving> *stream = (OFStream <OFReadyForReadingObserving> *)self; [OFRunLoop of_addAsyncReadLineForStream: stream encoding: encoding mode: runLoopMode block: block delegate: nil]; } # endif #endif - (OFString *)tryReadLine { return [self tryReadLineWithEncoding: OFStringEncodingUTF8]; } - (OFString *)tryReadTillDelimiter: (OFString *)delimiter encoding: (OFStringEncoding)encoding { const char *delimiterCString; size_t j, delimiterLength, pageSize, bufferLength; char *buffer, *readBuffer; OFString *ret; delimiterCString = [delimiter cStringWithEncoding: encoding]; delimiterLength = [delimiter cStringLengthWithEncoding: encoding]; j = 0; if (delimiterLength == 0) |
︙ | ︙ | |||
973 974 975 976 977 978 979 | return ret; } } } /* Read and see if we got a delimiter or \0 */ pageSize = [OFSystemInfo pageSize]; | | | > > > | < < < < | | | < | < | | < | > | | | | | | | | | > > | | | > > > > | | | | > | | > > > > > > > > > > > > > > > | | < < > > | > | < < | < | < | | | | | | | < | | | | | | | | | | | | | < < | | < < | | < < | | < < | | < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < < | | < < | | < < | | < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < > | < | < | < | | < | < | < | < | | < | < | | < | | < | < | < | < | < | < | < | | < < < | 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 | return ret; } } } /* Read and see if we got a delimiter or \0 */ pageSize = [OFSystemInfo pageSize]; buffer = OFAllocMemory(1, pageSize); @try { if ([self lowlevelIsAtEndOfStream]) { if (_readBuffer == NULL) { _waitingForDelimiter = false; return nil; } ret = [OFString stringWithCString: _readBuffer encoding: encoding length: _readBufferLength]; OFFreeMemory(_readBufferMemory); _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; _waitingForDelimiter = false; return ret; } bufferLength = [self lowlevelReadIntoBuffer: buffer length: pageSize]; /* Look if there's a delimiter or \0 */ for (size_t i = 0; i < bufferLength; i++) { if (buffer[i] != delimiterCString[j++]) j = 0; if (j == delimiterLength || buffer[i] == '\0') { size_t retLength; char *retCString; if (buffer[i] == '\0') delimiterLength = 1; retLength = _readBufferLength + i + 1 - delimiterLength; retCString = OFAllocMemory(retLength, 1); if (_readBuffer != NULL && _readBufferLength <= retLength) memcpy(retCString, _readBuffer, _readBufferLength); else if (_readBuffer != NULL) memcpy(retCString, _readBuffer, retLength); if (i >= delimiterLength) memcpy(retCString + _readBufferLength, buffer, i + 1 - delimiterLength); @try { ret = [OFString stringWithCString: retCString encoding: encoding length: retLength]; } @catch (id e) { if (bufferLength > 0) { /* * Append data to _readBuffer * to prevent loss of data. */ readBuffer = OFAllocMemory( _readBufferLength + bufferLength, 1); memcpy(readBuffer, _readBuffer, _readBufferLength); memcpy(readBuffer + _readBufferLength, buffer, bufferLength); OFFreeMemory(_readBufferMemory); _readBuffer = readBuffer; _readBufferMemory = readBuffer; _readBufferLength += bufferLength; } @throw e; } @finally { OFFreeMemory(retCString); } readBuffer = OFAllocMemory(bufferLength - i - 1, 1); if (readBuffer != NULL) memcpy(readBuffer, buffer + i + 1, bufferLength - i - 1); OFFreeMemory(_readBufferMemory); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength = bufferLength - i - 1; _waitingForDelimiter = false; return ret; } } /* Neither the delimiter nor \0 was found */ if (bufferLength > 0) { readBuffer = OFAllocMemory( _readBufferLength + bufferLength, 1); memcpy(readBuffer, _readBuffer, _readBufferLength); memcpy(readBuffer + _readBufferLength, buffer, bufferLength); OFFreeMemory(_readBufferMemory); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength += bufferLength; } } @finally { OFFreeMemory(buffer); } _waitingForDelimiter = true; return nil; } - (OFString *)readTillDelimiter: (OFString *)delimiter { return [self readTillDelimiter: delimiter encoding: OFStringEncodingUTF8]; } - (OFString *)readTillDelimiter: (OFString *)delimiter encoding: (OFStringEncoding)encoding { OFString *ret = nil; while ((ret = [self tryReadTillDelimiter: delimiter encoding: encoding]) == nil) if (self.atEndOfStream) return nil; return ret; } - (OFString *)tryReadTillDelimiter: (OFString *)delimiter { return [self tryReadTillDelimiter: delimiter encoding: OFStringEncodingUTF8]; } - (bool)flushWriteBuffer { size_t bytesWritten; if (_writeBuffer == NULL) return true; bytesWritten = [self lowlevelWriteBuffer: _writeBuffer length: _writeBufferLength]; if (bytesWritten == 0) return false; if (bytesWritten == _writeBufferLength) { OFFreeMemory(_writeBuffer); _writeBuffer = NULL; _writeBufferLength = 0; return true; } OFEnsure(bytesWritten <= _writeBufferLength); memmove(_writeBuffer, _writeBuffer + bytesWritten, _writeBufferLength - bytesWritten); _writeBufferLength -= bytesWritten; @try { _writeBuffer = OFResizeMemory(_writeBuffer, _writeBufferLength, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only made it smaller. */ } return false; } - (void)writeBuffer: (const void *)buffer length: (size_t)length { if (!_buffersWrites) { size_t bytesWritten = [self lowlevelWriteBuffer: buffer length: length]; if (bytesWritten < length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; } else { if (SIZE_MAX - _writeBufferLength < length) @throw [OFOutOfRangeException exception]; _writeBuffer = OFResizeMemory(_writeBuffer, _writeBufferLength + length, 1); memcpy(_writeBuffer + _writeBufferLength, buffer, length); _writeBufferLength += length; } } #ifdef OF_HAVE_SOCKETS - (void)asyncWriteData: (OFData *)data { [self asyncWriteData: data runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncWriteData: (OFData *)data runLoopMode: (OFRunLoopMode)runLoopMode { OFStream <OFReadyForWritingObserving> *stream = (OFStream <OFReadyForWritingObserving> *)self; [OFRunLoop of_addAsyncWriteForStream: stream data: data mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } - (void)asyncWriteString: (OFString *)string { [self asyncWriteString: string encoding: OFStringEncodingUTF8 runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncWriteString: (OFString *)string encoding: (OFStringEncoding)encoding { [self asyncWriteString: string encoding: encoding runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncWriteString: (OFString *)string encoding: (OFStringEncoding)encoding runLoopMode: (OFRunLoopMode)runLoopMode { OFStream <OFReadyForWritingObserving> *stream = (OFStream <OFReadyForWritingObserving> *)self; [OFRunLoop of_addAsyncWriteForStream: stream string: string encoding: encoding mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } # ifdef OF_HAVE_BLOCKS - (void)asyncWriteData: (OFData *)data block: (OFStreamAsyncWriteDataBlock)block { [self asyncWriteData: data runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncWriteData: (OFData *)data runLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamAsyncWriteDataBlock)block { OFStream <OFReadyForWritingObserving> *stream = (OFStream <OFReadyForWritingObserving> *)self; [OFRunLoop of_addAsyncWriteForStream: stream data: data mode: runLoopMode block: block delegate: nil]; } - (void)asyncWriteString: (OFString *)string block: (OFStreamAsyncWriteStringBlock)block { [self asyncWriteString: string encoding: OFStringEncodingUTF8 runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncWriteString: (OFString *)string encoding: (OFStringEncoding)encoding block: (OFStreamAsyncWriteStringBlock)block { [self asyncWriteString: string encoding: encoding runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncWriteString: (OFString *)string encoding: (OFStringEncoding)encoding runLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamAsyncWriteStringBlock)block { OFStream <OFReadyForWritingObserving> *stream = (OFStream <OFReadyForWritingObserving> *)self; [OFRunLoop of_addAsyncWriteForStream: stream string: string encoding: encoding mode: runLoopMode block: block delegate: nil]; } # endif #endif - (void)writeInt8: (uint8_t)int8 { [self writeBuffer: (char *)&int8 length: 1]; } - (void)writeBigEndianInt16: (uint16_t)int16 { int16 = OFToBigEndian16(int16); [self writeBuffer: (char *)&int16 length: 2]; } - (void)writeBigEndianInt32: (uint32_t)int32 { int32 = OFToBigEndian32(int32); [self writeBuffer: (char *)&int32 length: 4]; } - (void)writeBigEndianInt64: (uint64_t)int64 { int64 = OFToBigEndian64(int64); [self writeBuffer: (char *)&int64 length: 8]; } - (void)writeBigEndianFloat: (float)float_ { float_ = OFToBigEndianFloat(float_); [self writeBuffer: (char *)&float_ length: 4]; } - (void)writeBigEndianDouble: (double)double_ { double_ = OFToBigEndianDouble(double_); [self writeBuffer: (char *)&double_ length: 8]; } - (void)writeLittleEndianInt16: (uint16_t)int16 { int16 = OFToLittleEndian16(int16); [self writeBuffer: (char *)&int16 length: 2]; } - (void)writeLittleEndianInt32: (uint32_t)int32 { int32 = OFToLittleEndian32(int32); [self writeBuffer: (char *)&int32 length: 4]; } - (void)writeLittleEndianInt64: (uint64_t)int64 { int64 = OFToLittleEndian64(int64); [self writeBuffer: (char *)&int64 length: 8]; } - (void)writeLittleEndianFloat: (float)float_ { float_ = OFToLittleEndianFloat(float_); [self writeBuffer: (char *)&float_ length: 4]; } - (void)writeLittleEndianDouble: (double)double_ { double_ = OFToLittleEndianDouble(double_); [self writeBuffer: (char *)&double_ length: 8]; } - (void)writeData: (OFData *)data { void *pool; size_t length; if (data == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); length = data.count * data.itemSize; [self writeBuffer: data.items length: length]; objc_autoreleasePoolPop(pool); } - (void)writeString: (OFString *)string { [self writeString: string encoding: OFStringEncodingUTF8]; } - (void)writeString: (OFString *)string encoding: (OFStringEncoding)encoding { void *pool; size_t length; if (string == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); length = [string cStringLengthWithEncoding: encoding]; [self writeBuffer: [string cStringWithEncoding: encoding] length: length]; objc_autoreleasePoolPop(pool); } - (void)writeLine: (OFString *)string { [self writeLine: string encoding: OFStringEncodingUTF8]; } - (void)writeLine: (OFString *)string encoding: (OFStringEncoding)encoding { size_t stringLength = [string cStringLengthWithEncoding: encoding]; char *buffer; buffer = OFAllocMemory(stringLength + 1, 1); @try { memcpy(buffer, [string cStringWithEncoding: encoding], stringLength); buffer[stringLength] = '\n'; [self writeBuffer: buffer length: stringLength + 1]; } @finally { OFFreeMemory(buffer); } } - (void)writeFormat: (OFConstantString *)format, ... { va_list arguments; va_start(arguments, format); [self writeFormat: format arguments: arguments]; va_end(arguments); } - (void)writeFormat: (OFConstantString *)format arguments: (va_list)arguments { char *UTF8String; int length; if (format == nil) @throw [OFInvalidArgumentException exception]; if ((length = OFVASPrintF(&UTF8String, format.UTF8String, arguments)) == -1) @throw [OFInvalidFormatException exception]; @try { [self writeBuffer: UTF8String length: length]; } @finally { free(UTF8String); } } - (bool)hasDataInReadBuffer { return (_readBufferLength > 0); } |
︙ | ︙ | |||
1870 1871 1872 1873 1874 1875 1876 | OF_UNRECOGNIZED_SELECTOR } #ifdef OF_HAVE_SOCKETS - (void)cancelAsyncRequests { [OFRunLoop of_cancelAsyncRequestsForObject: self | | | < | | | | | 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 | OF_UNRECOGNIZED_SELECTOR } #ifdef OF_HAVE_SOCKETS - (void)cancelAsyncRequests { [OFRunLoop of_cancelAsyncRequestsForObject: self mode: OFDefaultRunLoopMode]; } #endif - (void)unreadFromBuffer: (const void *)buffer length: (size_t)length { char *readBuffer; if (length > SIZE_MAX - _readBufferLength) @throw [OFOutOfRangeException exception]; readBuffer = OFAllocMemory(_readBufferLength + length, 1); memcpy(readBuffer, buffer, length); memcpy(readBuffer + length, _readBuffer, _readBufferLength); OFFreeMemory(_readBufferMemory); _readBuffer = _readBufferMemory = readBuffer; _readBufferLength += length; } - (void)close { OFFreeMemory(_readBufferMemory); _readBuffer = _readBufferMemory = NULL; _readBufferLength = 0; OFFreeMemory(_writeBuffer); _writeBuffer = NULL; _writeBufferLength = 0; _buffersWrites = false; _waitingForDelimiter = false; } @end |
Modified src/OFStreamSocket+Private.h from [c1cf7136f2] to [a23e5c50d7].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFStreamSocket.h from [12e4e63247] to [5c1a8b3304].
1 | /* | < < | < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFStream.h" #import "OFSocket.h" OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFStreamSocket; #ifdef OF_HAVE_BLOCKS /** * @brief A block which is called when the socket accepted a connection. * * @param acceptedSocket The socket which has been accepted * @param exception An exception which occurred while accepting the socket or * `nil` on success * @return A bool whether the same block should be used for the next incoming * connection */ typedef bool (^OFStreamSocketAsyncAcceptBlock)(OFStreamSocket *acceptedSocket, id _Nullable exception); #endif /** * @protocol OFStreamSocketDelegate OFStreamSocket.h ObjFW/OFStreamSocket.h * * A delegate for OFStreamSocket. */ |
︙ | ︙ | |||
64 65 66 67 68 69 70 | * @class OFStreamSocket OFStreamSocket.h ObjFW/OFStreamSocket.h * * @brief A class which provides methods to create and use stream sockets. */ @interface OFStreamSocket: OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> { | | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | * @class OFStreamSocket OFStreamSocket.h ObjFW/OFStreamSocket.h * * @brief A class which provides methods to create and use stream sockets. */ @interface OFStreamSocket: OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> { OFSocketHandle _socket; bool _atEndOfStream, _listening; OFSocketAddress _remoteAddress; OF_RESERVE_IVARS(OFStreamSocket, 4) } /** * @brief Whether the socket is a listening socket. */ @property (readonly, nonatomic, getter=isListening) bool listening; /** * @brief The remote address. * * @note This only works for accepted sockets! */ @property (readonly, nonatomic) const OFSocketAddress *remoteAddress; /** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ |
︙ | ︙ | |||
127 128 129 130 131 132 133 | - (void)asyncAccept; /** * @brief Asynchronously accept an incoming connection. * * @param runLoopMode The run loop mode in which to perform the async accept */ | | | | < | | 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | - (void)asyncAccept; /** * @brief Asynchronously accept an incoming connection. * * @param runLoopMode The run loop mode in which to perform the async accept */ - (void)asyncAcceptWithRunLoopMode: (OFRunLoopMode)runLoopMode; #ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously accept an incoming connection. * * @param block The block to execute when a new connection has been accepted. * Returns whether the next incoming connection should be accepted * by the specified block as well. */ - (void)asyncAcceptWithBlock: (OFStreamSocketAsyncAcceptBlock)block; /** * @brief Asynchronously accept an incoming connection. * * @param runLoopMode The run loop mode in which to perform the async accept * @param block The block to execute when a new connection has been accepted. * Returns whether the next incoming connection should be accepted * by the specified block as well. */ - (void)asyncAcceptWithRunLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamSocketAsyncAcceptBlock)block; #endif @end OF_ASSUME_NONNULL_END |
Modified src/OFStreamSocket.m from [2df2daa037] to [f14a71e66a].
1 | /* | < < | > > > > > | < > < < | | | | | < | | | | < | | | | | | | | | | | | | | > | | | | | | > > > > > | < | | | | < | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #ifndef _XOPEN_SOURCE_EXTENDED # define _XOPEN_SOURCE_EXTENDED #endif #define __NO_EXT_QNX #define _HPUX_ALT_XOPEN_SOCKET_API #include <assert.h> #include <errno.h> #include <string.h> #import "OFStreamSocket.h" #import "OFStreamSocket+Private.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFSocket+Private.h" #import "OFAcceptFailedException.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFListenFailedException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFSetOptionFailedException.h" #import "OFWriteFailedException.h" @implementation OFStreamSocket @dynamic delegate; @synthesize listening = _listening; + (void)initialize { if (self != [OFStreamSocket class]) return; if (!OFSocketInit()) @throw [OFInitializationFailedException exceptionWithClass: self]; } + (instancetype)socket { return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; @try { if (self.class == [OFStreamSocket class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } _socket = OFInvalidSocketHandle; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_socket != OFInvalidSocketHandle) [self close]; [super dealloc]; } - (bool)lowlevelIsAtEndOfStream { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { ssize_t ret; if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; #ifndef OF_WINDOWS if ((ret = recv(_socket, buffer, length, 0)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: OFSocketErrNo()]; #else if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((ret = recv(_socket, buffer, (int)length, 0)) < 0) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: OFSocketErrNo()]; #endif if (ret == 0) _atEndOfStream = true; return ret; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; #ifndef OF_WINDOWS ssize_t bytesWritten; if (length > SSIZE_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = send(_socket, (void *)buffer, length, 0)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: OFSocketErrNo()]; #else int bytesWritten; if (length > INT_MAX) @throw [OFOutOfRangeException exception]; if ((bytesWritten = send(_socket, buffer, (int)length, 0)) < 0) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: 0 errNo: OFSocketErrNo()]; #endif return (size_t)bytesWritten; } #if defined(OF_WINDOWS) || defined(OF_AMIGAOS) - (void)setCanBlock: (bool)canBlock { # ifdef OF_WINDOWS u_long v = !canBlock; # else char v = !canBlock; # endif if (ioctlsocket(_socket, FIONBIO, &v) == SOCKET_ERROR) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: OFSocketErrNo()]; _canBlock = canBlock; } #endif - (int)fileDescriptorForReading { #ifndef OF_WINDOWS return _socket; #else if (_socket == OFInvalidSocketHandle) return -1; if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } - (int)fileDescriptorForWriting { #ifndef OF_WINDOWS return _socket; #else if (_socket == OFInvalidSocketHandle) return -1; if (_socket > INT_MAX) @throw [OFOutOfRangeException exception]; return (int)_socket; #endif } #ifndef OF_WII - (int)of_socketError { int errNo; socklen_t len = sizeof(errNo); if (getsockopt(_socket, SOL_SOCKET, SO_ERROR, (char *)&errNo, &len) != 0) return OFSocketErrNo(); return errNo; } #endif - (void)listen { [self listenWithBacklog: SOMAXCONN]; } - (void)listenWithBacklog: (int)backlog { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; if (listen(_socket, backlog) == -1) @throw [OFListenFailedException exceptionWithSocket: self backlog: backlog errNo: OFSocketErrNo()]; _listening = true; } - (instancetype)accept { OFStreamSocket *client = [[[[self class] alloc] init] autorelease]; #if (!defined(HAVE_PACCEPT) && !defined(HAVE_ACCEPT4)) || !defined(SOCK_CLOEXEC) # if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; # endif #endif client->_remoteAddress.length = (socklen_t)sizeof(client->_remoteAddress.sockaddr); #if defined(HAVE_PACCEPT) && defined(SOCK_CLOEXEC) if ((client->_socket = paccept(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length, NULL, SOCK_CLOEXEC)) == OFInvalidSocketHandle) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: OFSocketErrNo()]; #elif defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) if ((client->_socket = accept4(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length, SOCK_CLOEXEC)) == OFInvalidSocketHandle) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: OFSocketErrNo()]; #else if ((client->_socket = accept(_socket, &client->_remoteAddress.sockaddr.sockaddr, &client->_remoteAddress.length)) == OFInvalidSocketHandle) @throw [OFAcceptFailedException exceptionWithSocket: self errNo: OFSocketErrNo()]; # if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(client->_socket, F_GETFD, 0)) != -1) fcntl(client->_socket, F_SETFD, flags | FD_CLOEXEC); # endif #endif assert(client->_remoteAddress.length <= (socklen_t)sizeof(client->_remoteAddress.sockaddr)); switch (client->_remoteAddress.sockaddr.sockaddr.sa_family) { case AF_INET: client->_remoteAddress.family = OFSocketAddressFamilyIPv4; break; #ifdef OF_HAVE_IPV6 case AF_INET6: client->_remoteAddress.family = OFSocketAddressFamilyIPv6; break; #endif #ifdef OF_HAVE_IPX case AF_IPX: client->_remoteAddress.family = OFSocketAddressFamilyIPX; break; #endif #ifdef OF_HAVE_UNIX_SOCKETS case AF_UNIX: client->_remoteAddress.family = OFSocketAddressFamilyUNIX; break; #endif default: client->_remoteAddress.family = OFSocketAddressFamilyUnknown; break; } return client; } - (void)asyncAccept { [self asyncAcceptWithRunLoopMode: OFDefaultRunLoopMode]; } - (void)asyncAcceptWithRunLoopMode: (OFRunLoopMode)runLoopMode { [OFRunLoop of_addAsyncAcceptForSocket: self mode: runLoopMode block: NULL delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncAcceptWithBlock: (OFStreamSocketAsyncAcceptBlock)block { [self asyncAcceptWithRunLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncAcceptWithRunLoopMode: (OFRunLoopMode)runLoopMode block: (OFStreamSocketAsyncAcceptBlock)block { [OFRunLoop of_addAsyncAcceptForSocket: self mode: runLoopMode block: block delegate: nil]; } #endif - (const OFSocketAddress *)remoteAddress { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; if (_remoteAddress.length == 0) @throw [OFInvalidArgumentException exception]; if (_remoteAddress.length > (socklen_t)sizeof(_remoteAddress.sockaddr)) @throw [OFOutOfRangeException exception]; return &_remoteAddress; } - (void)close { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; _listening = false; memset(&_remoteAddress, 0, sizeof(_remoteAddress)); closesocket(_socket); _socket = OFInvalidSocketHandle; _atEndOfStream = false; [super close]; } @end |
Renamed and modified src/OFString+CryptoHashing.h [6628c49341] to src/OFString+CryptographicHashing.h [63c51821ee].
1 | /* | < < | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFString.h" OF_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { #endif extern int _OFString_CryptographicHashing_reference; #ifdef __cplusplus } #endif @interface OFString (CryptographicHashing) /** * @brief The MD5 hash of the string as a string. */ @property (readonly, nonatomic) OFString *stringByMD5Hashing; /** * @brief The RIPEMD-160 hash of the string as a string. */ @property (readonly, nonatomic) OFString *stringByRIPEMD160Hashing; /** * @brief The SHA-1 hash of the string as a string. */ @property (readonly, nonatomic) OFString *stringBySHA1Hashing; /** * @brief The SHA-224 hash of the string as a string. */ @property (readonly, nonatomic) OFString *stringBySHA224Hashing; /** * @brief The SHA-256 hash of the string as a string. */ @property (readonly, nonatomic) OFString *stringBySHA256Hashing; /** * @brief The SHA-384 hash of the string as a string. */ @property (readonly, nonatomic) OFString *stringBySHA384Hashing; /** * @brief The SHA-512 hash of the string as a string. */ @property (readonly, nonatomic) OFString *stringBySHA512Hashing; @end OF_ASSUME_NONNULL_END |
Renamed and modified src/OFString+CryptoHashing.m [9d43bb7986] to src/OFString+CryptographicHashing.m [30b5bea6f8].
1 | /* | < < | | | | | > | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "OFCryptographicHash.h" #import "OFMD5Hash.h" #import "OFRIPEMD160Hash.h" #import "OFSHA1Hash.h" #import "OFSHA224Hash.h" #import "OFSHA256Hash.h" #import "OFSHA384Hash.h" #import "OFSHA512Hash.h" int _OFString_CryptographicHashing_reference; @implementation OFString (CryptographicHashing) static OFString * stringByHashing(Class <OFCryptographicHash> class, OFString *self) { void *pool = objc_autoreleasePoolPush(); id <OFCryptographicHash> hash = [class hashWithAllowsSwappableMemory: true]; size_t digestSize = [class digestSize]; const unsigned char *digest; char cString[digestSize * 2]; [hash updateWithBuffer: self.UTF8String length: self.UTF8StringLength]; [hash calculate]; digest = hash.digest; for (size_t i = 0; i < digestSize; i++) { uint8_t high, low; high = digest[i] >> 4; low = digest[i] & 0x0F; cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0'); cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0'); } objc_autoreleasePoolPop(pool); return [OFString stringWithCString: cString encoding: OFStringEncodingASCII length: digestSize * 2]; } - (OFString *)stringByMD5Hashing { return stringByHashing([OFMD5Hash class], self); } - (OFString *)stringByRIPEMD160Hashing { return stringByHashing([OFRIPEMD160Hash class], self); } - (OFString *)stringBySHA1Hashing { return stringByHashing([OFSHA1Hash class], self); } - (OFString *)stringBySHA224Hashing { return stringByHashing([OFSHA224Hash class], self); } - (OFString *)stringBySHA256Hashing { return stringByHashing([OFSHA256Hash class], self); } - (OFString *)stringBySHA384Hashing { return stringByHashing([OFSHA384Hash class], self); } - (OFString *)stringBySHA512Hashing { return stringByHashing([OFSHA512Hash class], self); } @end |
Modified src/OFString+JSONParsing.h from [ca618a0ff6] to [ace137eeef].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFString+JSONParsing.m from [b73e42773d] to [5489126d7d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #import "OFString+JSONParsing.h" #import "OFArray.h" #import "OFDictionary.h" #import "OFNumber.h" #import "OFNull.h" #import "OFInvalidJSONException.h" int _OFString_JSONParsing_reference; static id nextObject(const char **pointer, const char *stop, size_t *line, size_t depthLimit); static void | > > > > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #import "OFString+JSONParsing.h" #import "OFArray.h" #import "OFDictionary.h" #import "OFNumber.h" #import "OFNull.h" #import "OFInvalidJSONException.h" #ifndef INFINITY # define INFINITY __builtin_inf() #endif int _OFString_JSONParsing_reference; static id nextObject(const char **pointer, const char *stop, size_t *line, size_t depthLimit); static void |
︙ | ︙ | |||
103 104 105 106 107 108 109 | old = *pointer; skipWhitespaces(pointer, stop, line); skipComment(pointer, stop, line); } } | | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | old = *pointer; skipWhitespaces(pointer, stop, line); skipComment(pointer, stop, line); } } static inline OFChar16 parseUnicodeEscape(const char *pointer, const char *stop) { OFChar16 ret = 0; if (pointer + 5 >= stop) return 0xFFFF; if (pointer[0] != '\\' || pointer[1] != 'u') return 0xFFFF; |
︙ | ︙ | |||
144 145 146 147 148 149 150 | char *buffer; size_t i = 0; char delimiter = **pointer; if (++(*pointer) + 1 >= stop) return nil; | | | | 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | char *buffer; size_t i = 0; char delimiter = **pointer; if (++(*pointer) + 1 >= stop) return nil; buffer = OFAllocMemory(stop - *pointer, 1); while (*pointer < stop) { /* Parse escape codes */ if (**pointer == '\\') { if (++(*pointer) >= stop) { OFFreeMemory(buffer); return nil; } switch (**pointer) { case '"': case '\\': case '/': |
︙ | ︙ | |||
183 184 185 186 187 188 189 | break; case 't': buffer[i++] = '\t'; (*pointer)++; break; /* Parse Unicode escape sequence */ case 'u':; | | | | | < | | | | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | break; case 't': buffer[i++] = '\t'; (*pointer)++; break; /* Parse Unicode escape sequence */ case 'u':; OFChar16 c1, c2; OFUnichar c; size_t l; c1 = parseUnicodeEscape(*pointer - 1, stop); if (c1 == 0xFFFF) { OFFreeMemory(buffer); return nil; } /* Low surrogate */ if ((c1 & 0xFC00) == 0xDC00) { OFFreeMemory(buffer); return nil; } /* Normal character */ if ((c1 & 0xFC00) != 0xD800) { l = OFUTF8StringEncode(c1, buffer + i); if (l == 0) { OFFreeMemory(buffer); return nil; } i += l; *pointer += 5; break; } /* * If we are still here, we only got one UTF-16 * surrogate and now need to get the other one * in order to produce UTF-8 and not CESU-8. */ c2 = parseUnicodeEscape(*pointer + 5, stop); if (c2 == 0xFFFF) { OFFreeMemory(buffer); return nil; } c = (((c1 & 0x3FF) << 10) | (c2 & 0x3FF)) + 0x10000; l = OFUTF8StringEncode(c, buffer + i); if (l == 0) { OFFreeMemory(buffer); return nil; } i += l; *pointer += 11; break; |
︙ | ︙ | |||
252 253 254 255 256 257 258 | break; case '\n': (*pointer)++; (*line)++; break; default: | | | | | | | | | | | | | | | | | | | | 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | break; case '\n': (*pointer)++; (*line)++; break; default: OFFreeMemory(buffer); return nil; } /* End of string found */ } else if (**pointer == delimiter) { OFString *ret; @try { ret = [OFString stringWithUTF8String: buffer length: i]; } @finally { OFFreeMemory(buffer); } (*pointer)++; return ret; /* Newlines in strings are disallowed */ } else if (**pointer == '\n' || **pointer == '\r') { (*line)++; OFFreeMemory(buffer); return nil; } else { buffer[i++] = **pointer; (*pointer)++; } } OFFreeMemory(buffer); return nil; } static inline OFString * parseIdentifier(const char **pointer, const char *stop) { char *buffer; size_t i = 0; buffer = OFAllocMemory(stop - *pointer, 1); while (*pointer < stop) { if ((**pointer >= 'a' && **pointer <= 'z') || (**pointer >= 'A' && **pointer <= 'Z') || (**pointer >= '0' && **pointer <= '9') || **pointer == '_' || **pointer == '$' || (**pointer & 0x80)) { buffer[i++] = **pointer; (*pointer)++; } else if (**pointer == '\\') { OFChar16 c1, c2; OFUnichar c; size_t l; if (++(*pointer) >= stop || **pointer != 'u') { OFFreeMemory(buffer); return nil; } c1 = parseUnicodeEscape(*pointer - 1, stop); if (c1 == 0xFFFF) { OFFreeMemory(buffer); return nil; } /* Low surrogate */ if ((c1 & 0xFC00) == 0xDC00) { OFFreeMemory(buffer); return nil; } /* Normal character */ if ((c1 & 0xFC00) != 0xD800) { l = OFUTF8StringEncode(c1, buffer + i); if (l == 0) { OFFreeMemory(buffer); return nil; } i += l; *pointer += 5; continue; } /* * If we are still here, we only got one UTF-16 * surrogate and now need to get the other one in order * to produce UTF-8 and not CESU-8. */ c2 = parseUnicodeEscape(*pointer + 5, stop); if (c2 == 0xFFFF) { OFFreeMemory(buffer); return nil; } c = (((c1 & 0x3FF) << 10) | (c2 & 0x3FF)) + 0x10000; l = OFUTF8StringEncode(c, buffer + i); if (l == 0) { OFFreeMemory(buffer); return nil; } i += l; *pointer += 11; } else { OFString *ret; if (i == 0 || (buffer[0] >= '0' && buffer[0] <= '9')) { OFFreeMemory(buffer); return nil; } @try { ret = [OFString stringWithUTF8String: buffer length: i]; } @finally { OFFreeMemory(buffer); } return ret; } } /* * It is never possible to end with an identifier, thus we should never * reach stop. */ OFFreeMemory(buffer); return nil; } static inline OFMutableArray * parseArray(const char **pointer, const char *stop, size_t *line, size_t depthLimit) { |
︙ | ︙ | |||
498 499 500 501 502 503 504 | (*pointer)++; object = nextObject(pointer, stop, line, depthLimit); if (object == nil) return nil; | | < | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | (*pointer)++; object = nextObject(pointer, stop, line, depthLimit); if (object == nil) return nil; [dictionary setObject: object forKey: key]; skipWhitespacesAndComments(pointer, stop, line); if (*pointer >= stop) return nil; if (**pointer == ',') { (*pointer)++; |
︙ | ︙ | |||
544 545 546 547 548 549 550 | if ((*pointer)[i] == '\n') (*line)++; break; } } | | < | 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 | if ((*pointer)[i] == '\n') (*line)++; break; } } string = [[OFString alloc] initWithUTF8String: *pointer length: i]; *pointer += i; @try { if (hasDecimal) number = [OFNumber numberWithDouble: string.doubleValue]; else if ([string isEqual: @"Infinity"]) |
︙ | ︙ |
Modified src/OFString+PathAdditions.h from [9755ca9fad] to [c69c663e20].
1 | /* | < < | < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFString.h" OF_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { #endif extern int _OFString_PathAdditions_reference; #ifdef __cplusplus } #endif |
︙ | ︙ |
Modified src/OFString+PathAdditions.m from [ea666f96ec] to [422d7384b5].
1 | /* | < < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #if defined(OF_WINDOWS) || defined(OF_MSDOS) || defined(OF_MINT) # import "platform/Windows/OFString+PathAdditions.m" #elif defined(OF_AMIGAOS) # import "platform/AmigaOS/OFString+PathAdditions.m" #elif defined(OF_NINTENDO_3DS) || defined(OF_WII) # import "platform/libfat/OFString+PathAdditions.m" #else # import "platform/POSIX/OFString+PathAdditions.m" #endif |
Modified src/OFString+PropertyListParsing.h from [de40cce278] to [c22c9f1090].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFString+PropertyListParsing.m from [3c0b0b5b63] to [4a79f533f5].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
64 65 66 67 68 69 70 | enumerator = [children objectEnumerator]; while ((key = [enumerator nextObject]) && (object = [enumerator nextObject])) { if (key.namespace != nil || key.attributes.count != 0 || ![key.name isEqual: @"key"]) @throw [OFInvalidFormatException exception]; | | < | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | enumerator = [children objectEnumerator]; while ((key = [enumerator nextObject]) && (object = [enumerator nextObject])) { if (key.namespace != nil || key.attributes.count != 0 || ![key.name isEqual: @"key"]) @throw [OFInvalidFormatException exception]; [ret setObject: parseElement(object) forKey: key.stringValue]; } [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; |
︙ | ︙ |
Modified src/OFString+Serialization.h from [0280f20096] to [2c9a0f8857].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFString+Serialization.m from [0b468db6b6] to [feafb9e064].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
52 53 54 55 56 57 58 | if (version == nil) @throw [OFInvalidArgumentException exception]; if (version.unsignedLongLongValue != 1) @throw [OFUnsupportedVersionException exceptionWithVersion: version]; | | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | if (version == nil) @throw [OFInvalidArgumentException exception]; if (version.unsignedLongLongValue != 1) @throw [OFUnsupportedVersionException exceptionWithVersion: version]; elements = [root elementsForNamespace: OFSerializationNS]; if (elements.count != 1) @throw [OFInvalidArgumentException exception]; object = [[elements.firstObject objectByDeserializing] retain]; objc_autoreleasePoolPop(pool); return [object autorelease]; } @end |
Modified src/OFString+URLEncoding.h from [becefbf01f] to [b50441492b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFString+URLEncoding.m from [0c0207b5a6] to [7c362d8c35].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
32 33 34 35 36 37 38 | @implementation OFString (URLEncoding) - (OFString *)stringByURLEncodingWithAllowedCharacters: (OFCharacterSet *)allowedCharacters { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); | | | | | | < | | < > | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | @implementation OFString (URLEncoding) - (OFString *)stringByURLEncodingWithAllowedCharacters: (OFCharacterSet *)allowedCharacters { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); const OFUnichar *characters = self.characters; size_t length = self.length; bool (*characterIsMember)(id, SEL, OFUnichar) = (bool (*)(id, SEL, OFUnichar))[allowedCharacters methodForSelector: @selector(characterIsMember:)]; for (size_t i = 0; i < length; i++) { OFUnichar c = characters[i]; if (characterIsMember(allowedCharacters, @selector(characterIsMember:), c)) [ret appendCharacters: &c length: 1]; else { char buffer[4]; size_t bufferLen; if ((bufferLen = OFUTF8StringEncode(c, buffer)) == 0) @throw [OFInvalidEncodingException exception]; for (size_t j = 0; j < bufferLen; j++) { unsigned char byte = buffer[j]; unsigned char high = byte >> 4; unsigned char low = byte & 0x0F; char escaped[3]; escaped[0] = '%'; escaped[1] = (high > 9 ? high - 10 + 'A' : high + '0'); escaped[2] = (low > 9 ? low - 10 + 'A' : low + '0'); [ret appendUTF8String: escaped length: 3]; } } } objc_autoreleasePoolPop(pool); return ret; } - (OFString *)stringByURLDecoding { void *pool = objc_autoreleasePoolPush(); const char *string = self.UTF8String; size_t length = self.UTF8StringLength; char *retCString; char byte = 0; int state = 0; size_t i = 0; OFString *ret; retCString = OFAllocMemory(length + 1, 1); while (length--) { char c = *string++; switch (state) { case 0: if (c == '%') |
︙ | ︙ | |||
108 109 110 111 112 113 114 | if (c >= '0' && c <= '9') byte += (c - '0') << shift; else if (c >= 'A' && c <= 'F') byte += (c - 'A' + 10) << shift; else if (c >= 'a' && c <= 'f') byte += (c - 'a' + 10) << shift; else { | | | | > | | | > > > | > > > | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | if (c >= '0' && c <= '9') byte += (c - '0') << shift; else if (c >= 'A' && c <= 'F') byte += (c - 'A' + 10) << shift; else if (c >= 'a' && c <= 'f') byte += (c - 'a' + 10) << shift; else { OFFreeMemory(retCString); @throw [OFInvalidFormatException exception]; } if (++state == 3) { retCString[i++] = byte; state = 0; byte = 0; } break; } } retCString[i] = '\0'; objc_autoreleasePoolPop(pool); if (state != 0) { OFFreeMemory(retCString); @throw [OFInvalidFormatException exception]; } @try { retCString = OFResizeMemory(retCString, 1, i + 1); } @catch (OFOutOfMemoryException *e) { /* We don't care if it fails, as we only made it smaller. */ } @try { ret = [OFString stringWithUTF8StringNoCopy: retCString length: i freeWhenDone: true]; } @catch (id e) { OFFreeMemory(retCString); @throw e; } return ret; } @end |
Modified src/OFString+XMLEscaping.h from [a998c62996] to [5e7ff84170].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFString+XMLEscaping.m from [5d08b70ba3] to [417a4985be].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
38 39 40 41 42 43 44 | OFString *ret; string = self.UTF8String; length = self.UTF8StringLength; j = 0; retLength = length; | | < < < < | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | OFString *ret; string = self.UTF8String; length = self.UTF8StringLength; j = 0; retLength = length; retCString = OFAllocMemory(retLength, 1); for (size_t i = 0; i < length; i++) { switch (string[i]) { case '<': append = "<"; appendLen = 4; break; |
︙ | ︙ | |||
77 78 79 80 81 82 83 | default: append = NULL; appendLen = 0; } if (append != NULL) { @try { | | | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | default: append = NULL; appendLen = 0; } if (append != NULL) { @try { retCString = OFResizeMemory(retCString, 1, retLength + appendLen); } @catch (id e) { OFFreeMemory(retCString); @throw e; } retLength += appendLen - 1; memcpy(retCString + j, append, appendLen); j += appendLen; } else retCString[j++] = string[i]; } assert(j == retLength); objc_autoreleasePoolPop(pool); @try { ret = [OFString stringWithUTF8String: retCString length: retLength]; } @finally { OFFreeMemory(retCString); } return ret; } @end |
Modified src/OFString+XMLUnescaping.h from [0d82938925] to [f15d871a62].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
34 35 36 37 38 39 40 | * @brief A block which is called to replace unknown XML entities in an XML * string. * * @param string The XML string which contains an unknown entity * @param entity The XML entity which is unknown * @return A replacement string for the unknown entity */ | | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | * @brief A block which is called to replace unknown XML entities in an XML * string. * * @param string The XML string which contains an unknown entity * @param entity The XML entity which is unknown * @return A replacement string for the unknown entity */ typedef OFString *_Nullable (^OFStringXMLUnescapingBlock)(OFString *string, OFString *entity); #endif /** * @protocol OFStringXMLUnescapingDelegate OFString.h ObjFW/OFString.h * * @brief A protocol that needs to be implemented by delegates for * stringByXMLUnescapingWithHandler:. |
︙ | ︙ | |||
83 84 85 86 87 88 89 | #ifdef OF_HAVE_BLOCKS /** * @brief Unescapes XML in the string and uses the specified block for unknown * entities. * * @param block A block which handles unknown entities */ | | < | 81 82 83 84 85 86 87 88 89 90 91 92 | #ifdef OF_HAVE_BLOCKS /** * @brief Unescapes XML in the string and uses the specified block for unknown * entities. * * @param block A block which handles unknown entities */ - (OFString *)stringByXMLUnescapingWithBlock: (OFStringXMLUnescapingBlock)block; #endif @end OF_ASSUME_NONNULL_END |
Modified src/OFString+XMLUnescaping.m from [0954130a1e] to [dd8350c1c8].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | #import "OFUnknownXMLEntityException.h" int _OFString_XMLUnescaping_reference; static OF_INLINE OFString * parseNumericEntity(const char *entity, size_t length) { | | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #import "OFUnknownXMLEntityException.h" int _OFString_XMLUnescaping_reference; static OF_INLINE OFString * parseNumericEntity(const char *entity, size_t length) { OFUnichar c; size_t i; char buffer[5]; if (length == 1 || *entity != '#') return nil; c = 0; |
︙ | ︙ | |||
62 63 64 65 66 67 68 | if (entity[i] >= '0' && entity[i] <= '9') c = (c * 10) + (entity[i] - '0'); else return nil; } } | | | < | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | if (entity[i] >= '0' && entity[i] <= '9') c = (c * 10) + (entity[i] - '0'); else return nil; } } if ((i = OFUTF8StringEncode(c, buffer)) == 0) return nil; buffer[i] = 0; return [OFString stringWithUTF8String: buffer length: i]; } static OFString * parseEntities(OFString *self, id (*lookup)(void *, OFString *, OFString *), void *context) { OFMutableString *ret; |
︙ | ︙ | |||
92 93 94 95 96 97 98 | length = self.UTF8StringLength; last = 0; inEntity = false; for (i = 0; i < length; i++) { if (!inEntity && string[i] == '&') { | | < < | | | | | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | length = self.UTF8StringLength; last = 0; inEntity = false; for (i = 0; i < length; i++) { if (!inEntity && string[i] == '&') { [ret appendUTF8String: string + last length: i - last]; last = i + 1; inEntity = true; } else if (inEntity && string[i] == ';') { const char *entity = string + last; size_t entityLength = i - last; if (entityLength == 2 && memcmp(entity, "lt", 2) == 0) [ret appendCString: "<" encoding: OFStringEncodingASCII length: 1]; else if (entityLength == 2 && memcmp(entity, "gt", 2) == 0) [ret appendCString: ">" encoding: OFStringEncodingASCII length: 1]; else if (entityLength == 4 && memcmp(entity, "quot", 4) == 0) [ret appendCString: "\"" encoding: OFStringEncodingASCII length: 1]; else if (entityLength == 4 && memcmp(entity, "apos", 4) == 0) [ret appendCString: "'" encoding: OFStringEncodingASCII length: 1]; else if (entityLength == 3 && memcmp(entity, "amp", 3) == 0) [ret appendCString: "&" encoding: OFStringEncodingASCII length: 1]; else if (entity[0] == '#') { void *pool2; OFString *tmp; pool2 = objc_autoreleasePoolPush(); tmp = parseNumericEntity(entity, |
︙ | ︙ | |||
168 169 170 171 172 173 174 | inEntity = false; } } if (inEntity) @throw [OFInvalidFormatException exception]; | | < < < | | | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | inEntity = false; } } if (inEntity) @throw [OFInvalidFormatException exception]; [ret appendUTF8String: string + last length: i - last]; [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } static id lookupUsingDelegate(void *context, OFString *self, OFString *entity) { id <OFStringXMLUnescapingDelegate> delegate = context; if (delegate == nil) return nil; return [delegate string: self containsUnknownEntityNamed: entity]; } #ifdef OF_HAVE_BLOCKS static id lookupUsingBlock(void *context, OFString *self, OFString *entity) { OFStringXMLUnescapingBlock block = context; if (block == NULL) return nil; return block(self, entity); } #endif |
︙ | ︙ | |||
216 217 218 219 220 221 222 | - (OFString *)stringByXMLUnescapingWithDelegate: (id <OFStringXMLUnescapingDelegate>)delegate { return parseEntities(self, lookupUsingDelegate, delegate); } #ifdef OF_HAVE_BLOCKS | | < | 208 209 210 211 212 213 214 215 216 217 218 219 220 | - (OFString *)stringByXMLUnescapingWithDelegate: (id <OFStringXMLUnescapingDelegate>)delegate { return parseEntities(self, lookupUsingDelegate, delegate); } #ifdef OF_HAVE_BLOCKS - (OFString *)stringByXMLUnescapingWithBlock: (OFStringXMLUnescapingBlock)block { return parseEntities(self, lookupUsingBlock, block); } #endif @end |
Modified src/OFString.h from [b31ea8640a] to [b34719db3c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
52 53 54 55 56 57 58 | @class OFConstantString; @class OFString; #else typedef void OFString; #endif #if defined(__cplusplus) && __cplusplus >= 201103L | | | | | | | | | | | | | | | | | | | | | | | > > > > > | > | > | < > > > > > > > > > | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | @class OFConstantString; @class OFString; #else typedef void OFString; #endif #if defined(__cplusplus) && __cplusplus >= 201103L typedef char16_t OFChar16; typedef char32_t OFChar32; #else typedef uint_least16_t OFChar16; typedef uint_least32_t OFChar32; #endif typedef OFChar32 OFUnichar; /** * @brief The encoding of a string. */ typedef enum { /* * UTF-8 *has* to be 0, so that if the current @ref OFLocale is * `nil`, `[OFLocale encoding]` returns UTF-8. */ /** UTF-8 */ OFStringEncodingUTF8, /** ASCII */ OFStringEncodingASCII, /** ISO 8859-1 */ OFStringEncodingISO8859_1, /** ISO 8859-2 */ OFStringEncodingISO8859_2, /** ISO 8859-3 */ OFStringEncodingISO8859_3, /** ISO 8859-15 */ OFStringEncodingISO8859_15, /** Windows-1251 */ OFStringEncodingWindows1251, /** Windows-1252 */ OFStringEncodingWindows1252, /** Codepage 437 */ OFStringEncodingCodepage437, /** Codepage 850 */ OFStringEncodingCodepage850, /** Codepage 858 */ OFStringEncodingCodepage858, /** Mac OS Roman */ OFStringEncodingMacRoman, /** KOI8-R */ OFStringEncodingKOI8R, /** KOI8-U */ OFStringEncodingKOI8U, /** Try to automatically detect the encoding */ OFStringEncodingAutodetect = 0xFF } OFStringEncoding; /** * @brief Options for searching in strings. * * This is a bit mask. */ typedef enum { /** Search backwards in the string */ OFStringSearchBackwards = 1 } OFStringSearchOptions; /** * @brief Options for separating strings. * * This is a bit mask. */ typedef enum { /** Skip empty components */ OFStringSkipEmptyComponents = 1 } OFStringSeparationOptions; #ifdef OF_HAVE_BLOCKS /** * @brief A block for enumerating the lines of a string. * * @param line The current line * @param stop A pointer to a variable that can be set to true to stop the * enumeration */ typedef void (^OFStringLineEnumerationBlock)(OFString *line, bool *stop); #endif #ifdef __OBJC__ @class OFArray OF_GENERIC(ObjectType); @class OFCharacterSet; @class OFURL; |
︙ | ︙ | |||
215 216 217 218 219 220 221 | /** * @brief The string as an array of Unicode characters. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. */ | | | | | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | /** * @brief The string as an array of Unicode characters. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. */ @property (readonly, nonatomic) const OFUnichar *characters OF_RETURNS_INNER_POINTER; /** * @brief The string in UTF-16 encoding with native byte order. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. */ @property (readonly, nonatomic) const OFChar16 *UTF16String OF_RETURNS_INNER_POINTER; /** * @brief The length of the string in UTF-16 characters. */ @property (readonly, nonatomic) size_t UTF16StringLength; /** * @brief The string in UTF-32 encoding with native byte order. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. */ @property (readonly, nonatomic) const OFChar32 *UTF32String OF_RETURNS_INNER_POINTER; /** * @brief The string with leading whitespaces deleted. */ @property (readonly, nonatomic) OFString *stringByDeletingLeadingWhitespaces; |
︙ | ︙ | |||
309 310 311 312 313 314 315 | + (instancetype)stringWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength; /** * @brief Creates a new OFString from a UTF-8 encoded C string without copying * the string, if possible. * | | | | | | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | + (instancetype)stringWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength; /** * @brief Creates a new OFString from a UTF-8 encoded C string without copying * the string, if possible. * * If initialization fails for whatever reason, the passed C string is *not* * free'd if `freeWhenDone` is true. * * @note OFMutableString always creates a copy! * * @param UTF8String A UTF-8 encoded C string to initialize the OFString with * @param freeWhenDone Whether to free the C string when the OFString gets * deallocated * @return A new autoreleased OFString */ + (instancetype)stringWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone; /** * @brief Creates a new OFString from a UTF-8 encoded C string with the * specified length without copying the string, if possible. * * If initialization fails for whatever reason, the passed C string is *not* * free'd if `freeWhenDone` is true. * * @note OFMutableString always creates a copy! * * @param UTF8String A UTF-8 encoded C string to initialize the OFString with * @param UTF8StringLength The length of the UTF-8 encoded C string * @param freeWhenDone Whether to free the C string when the OFString gets * deallocated |
︙ | ︙ | |||
349 350 351 352 353 354 355 | * @brief Creates a new OFString from a C string with the specified encoding. * * @param cString A C string to initialize the OFString with * @param encoding The encoding of the C string * @return A new autoreleased OFString */ + (instancetype)stringWithCString: (const char *)cString | | | | | | | | | | | | | | | | | | | | 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | * @brief Creates a new OFString from a C string with the specified encoding. * * @param cString A C string to initialize the OFString with * @param encoding The encoding of the C string * @return A new autoreleased OFString */ + (instancetype)stringWithCString: (const char *)cString encoding: (OFStringEncoding)encoding; /** * @brief Creates a new OFString from a C string with the specified encoding * and length. * * @param cString A C string to initialize the OFString with * @param encoding The encoding of the C string * @param cStringLength The length of the C string * @return A new autoreleased OFString */ + (instancetype)stringWithCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength; /** * @brief Creates a new OFString from OFData with the specified encoding. * * @param data OFData with the contents of the string * @param encoding The encoding in which the string is stored in the OFData * @return An new autoreleased OFString */ + (instancetype)stringWithData: (OFData *)data encoding: (OFStringEncoding)encoding; /** * @brief Creates a new OFString from another string. * * @param string A string to initialize the OFString with * @return A new autoreleased OFString */ + (instancetype)stringWithString: (OFString *)string; /** * @brief Creates a new OFString from a Unicode string with the specified * length. * * @param characters An array of Unicode characters * @param length The length of the Unicode character array * @return A new autoreleased OFString */ + (instancetype)stringWithCharacters: (const OFUnichar *)characters length: (size_t)length; /** * @brief Creates a new OFString from a UTF-16 encoded string. * * @param string The UTF-16 string * @return A new autoreleased OFString */ + (instancetype)stringWithUTF16String: (const OFChar16 *)string; /** * @brief Creates a new OFString from a UTF-16 encoded string with the * specified length. * * @param string The UTF-16 string * @param length The length of the UTF-16 string * @return A new autoreleased OFString */ + (instancetype)stringWithUTF16String: (const OFChar16 *)string length: (size_t)length; /** * @brief Creates a new OFString from a UTF-16 encoded string, assuming the * specified byte order if no byte order mark is found. * * @param string The UTF-16 string * @param byteOrder The byte order to assume if there is no byte order mark * @return A new autoreleased OFString */ + (instancetype)stringWithUTF16String: (const OFChar16 *)string byteOrder: (OFByteOrder)byteOrder; /** * @brief Creates a new OFString from a UTF-16 encoded string with the * specified length, assuming the specified byte order if no byte order * mark is found. * * @param string The UTF-16 string * @param length The length of the UTF-16 string * @param byteOrder The byte order to assume if there is no byte order mark * @return A new autoreleased OFString */ + (instancetype)stringWithUTF16String: (const OFChar16 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder; /** * @brief Creates a new OFString from a UTF-32 encoded string. * * @param string The UTF-32 string * @return A new autoreleased OFString */ + (instancetype)stringWithUTF32String: (const OFChar32 *)string; /** * @brief Creates a new OFString from a UTF-32 encoded string with the * specified length. * * @param string The UTF-32 string * @param length The length of the UTF-32 string * @return A new autoreleased OFString */ + (instancetype)stringWithUTF32String: (const OFChar32 *)string length: (size_t)length; /** * @brief Creates a new OFString from a UTF-32 encoded string, assuming the * specified byte order if no byte order mark is found. * * @param string The UTF-32 string * @param byteOrder The byte order to assume if there is no byte order mark * @return A new autoreleased OFString */ + (instancetype)stringWithUTF32String: (const OFChar32 *)string byteOrder: (OFByteOrder)byteOrder; /** * @brief Creates a new OFString from a UTF-32 encoded string with the * specified length, assuming the specified byte order if no byte order * mark is found. * * @param string The UTF-32 string * @param length The length of the UTF-32 string * @param byteOrder The byte order to assume if there is no byte order mark * @return A new autoreleased OFString */ + (instancetype)stringWithUTF32String: (const OFChar32 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder; /** * @brief Creates a new OFString from a format string. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `OFUnichar` and `%S` for * `const OFUnichar *`. * * @param format A string used as format to initialize the OFString * @return A new autoreleased OFString */ + (instancetype)stringWithFormat: (OFConstantString *)format, ...; # ifdef OF_HAVE_FILES |
︙ | ︙ | |||
512 513 514 515 516 517 518 | * specified encoding. * * @param path The path to the file * @param encoding The encoding of the file * @return A new autoreleased OFString */ + (instancetype)stringWithContentsOfFile: (OFString *)path | | < | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 | * specified encoding. * * @param path The path to the file * @param encoding The encoding of the file * @return A new autoreleased OFString */ + (instancetype)stringWithContentsOfFile: (OFString *)path encoding: (OFStringEncoding)encoding; # endif /** * @brief Creates a new OFString with the contents of the specified URL. * * If the URL's scheme is file, it tries UTF-8 encoding. * * If the URL's scheme is http(s), it tries to detect the encoding from the HTTP * headers. If it could not detect the encoding using the HTTP headers, it tries |
︙ | ︙ | |||
539 540 541 542 543 544 545 | * specified encoding. * * @param URL The URL to the contents for the string * @param encoding The encoding to assume * @return A new autoreleased OFString */ + (instancetype)stringWithContentsOfURL: (OFURL *)URL | | < | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 | * specified encoding. * * @param URL The URL to the contents for the string * @param encoding The encoding to assume * @return A new autoreleased OFString */ + (instancetype)stringWithContentsOfURL: (OFURL *)URL encoding: (OFStringEncoding)encoding; /** * @brief Initializes an already allocated OFString from a UTF-8 encoded C * string. * * @param UTF8String A UTF-8 encoded C string to initialize the OFString with * @return An initialized OFString |
︙ | ︙ | |||
566 567 568 569 570 571 572 | - (instancetype)initWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength; /** * @brief Initializes an already allocated OFString from an UTF-8 encoded C * string without copying the string, if possible. * | | | | | | 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 | - (instancetype)initWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength; /** * @brief Initializes an already allocated OFString from an UTF-8 encoded C * string without copying the string, if possible. * * If initialization fails for whatever reason, the passed C string is *not* * free'd if `freeWhenDone` is true. * * @note OFMutableString always creates a copy! * * @param UTF8String A UTF-8 encoded C string to initialize the OFString with * @param freeWhenDone Whether to free the C string when it is not needed * anymore * @return An initialized OFString */ - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone; /** * @brief Initializes an already allocated OFString from an UTF-8 encoded C * string with the specified length without copying the string, if * possible. * * If initialization fails for whatever reason, the passed C string is *not* * free'd if `freeWhenDone` is true. * * @note OFMutableString always creates a copy! * * @param UTF8String A UTF-8 encoded C string to initialize the OFString with * @param UTF8StringLength The length of the UTF-8 encoded C string * @param freeWhenDone Whether to free the C string when it is not needed * anymore |
︙ | ︙ | |||
608 609 610 611 612 613 614 | * specified encoding. * * @param cString A C string to initialize the OFString with * @param encoding The encoding of the C string * @return An initialized OFString */ - (instancetype)initWithCString: (const char *)cString | | | | | | | | | | | | | | | | | | | | | | 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 | * specified encoding. * * @param cString A C string to initialize the OFString with * @param encoding The encoding of the C string * @return An initialized OFString */ - (instancetype)initWithCString: (const char *)cString encoding: (OFStringEncoding)encoding; /** * @brief Initializes an already allocated OFString from a C string with the * specified encoding and length. * * @param cString A C string to initialize the OFString with * @param encoding The encoding of the C string * @param cStringLength The length of the C string * @return An initialized OFString */ - (instancetype)initWithCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength; /** * @brief Initializes an already allocated OFString from OFData with the * specified encoding. * * @param data OFData with the contents of the string * @param encoding The encoding in which the string is stored in the OFData * @return An initialized OFString */ - (instancetype)initWithData: (OFData *)data encoding: (OFStringEncoding)encoding; /** * @brief Initializes an already allocated OFString with another string. * * @param string A string to initialize the OFString with * @return An initialized OFString */ - (instancetype)initWithString: (OFString *)string; /** * @brief Initializes an already allocated OFString with a Unicode string with * the specified length. * * @param characters An array of Unicode characters * @param length The length of the Unicode character array * @return An initialized OFString */ - (instancetype)initWithCharacters: (const OFUnichar *)characters length: (size_t)length; /** * @brief Initializes an already allocated OFString with a UTF-16 string. * * @param string The UTF-16 string * @return An initialized OFString */ - (instancetype)initWithUTF16String: (const OFChar16 *)string; /** * @brief Initializes an already allocated OFString with a UTF-16 string with * the specified length. * * @param string The UTF-16 string * @param length The length of the UTF-16 string * @return An initialized OFString */ - (instancetype)initWithUTF16String: (const OFChar16 *)string length: (size_t)length; /** * @brief Initializes an already allocated OFString with a UTF-16 string, * assuming the specified byte order if no byte order mark is found. * * @param string The UTF-16 string * @param byteOrder The byte order to assume if there is no byte order mark * @return An initialized OFString */ - (instancetype)initWithUTF16String: (const OFChar16 *)string byteOrder: (OFByteOrder)byteOrder; /** * @brief Initializes an already allocated OFString with a UTF-16 string with * the specified length, assuming the specified byte order if no byte * order mark is found. * * @param string The UTF-16 string * @param length The length of the UTF-16 string * @param byteOrder The byte order to assume if there is no byte order mark * @return An initialized OFString */ - (instancetype)initWithUTF16String: (const OFChar16 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder; /** * @brief Initializes an already allocated OFString with a UTF-32 string. * * @param string The UTF-32 string * @return An initialized OFString */ - (instancetype)initWithUTF32String: (const OFChar32 *)string; /** * @brief Initializes an already allocated OFString with a UTF-32 string with * the specified length * * @param string The UTF-32 string * @param length The length of the UTF-32 string * @return An initialized OFString */ - (instancetype)initWithUTF32String: (const OFChar32 *)string length: (size_t)length; /** * @brief Initializes an already allocated OFString with a UTF-32 string, * assuming the specified byte order if no byte order mark is found. * * @param string The UTF-32 string * @param byteOrder The byte order to assume if there is no byte order mark * @return An initialized OFString */ - (instancetype)initWithUTF32String: (const OFChar32 *)string byteOrder: (OFByteOrder)byteOrder; /** * @brief Initializes an already allocated OFString with a UTF-32 string with * the specified length, assuming the specified byte order if no byte * order mark is found. * * @param string The UTF-32 string * @param length The length of the UTF-32 string * @param byteOrder The byte order to assume if there is no byte order mark * @return An initialized OFString */ - (instancetype)initWithUTF32String: (const OFChar32 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder; /** * @brief Initializes an already allocated OFString with a format string. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `OFUnichar` and `%S` for * `const OFUnichar *`. * * @param format A string used as format to initialize the OFString * @return An initialized OFString */ - (instancetype)initWithFormat: (OFConstantString *)format, ...; /** * @brief Initializes an already allocated OFString with a format string. * * See printf for the format syntax. As an addition, `%@` is available as * format specifier for objects, `%C` for `OFUnichar` and `%S` for * `const OFUnichar *`. * * @param format A string used as format to initialize the OFString * @param arguments The arguments used in the format string * @return An initialized OFString */ - (instancetype)initWithFormat: (OFConstantString *)format arguments: (va_list)arguments; |
︙ | ︙ | |||
786 787 788 789 790 791 792 | * specified file in the specified encoding. * * @param path The path to the file * @param encoding The encoding of the file * @return An initialized OFString */ - (instancetype)initWithContentsOfFile: (OFString *)path | | | 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 | * specified file in the specified encoding. * * @param path The path to the file * @param encoding The encoding of the file * @return An initialized OFString */ - (instancetype)initWithContentsOfFile: (OFString *)path encoding: (OFStringEncoding)encoding; # endif /** * @brief Initializes an already allocated OFString with the contents of the * specified URL. * * If the URL's scheme is file, it tries UTF-8 encoding. |
︙ | ︙ | |||
813 814 815 816 817 818 819 | * specified URL in the specified encoding. * * @param URL The URL to the contents for the string * @param encoding The encoding to assume * @return An initialized OFString */ - (instancetype)initWithContentsOfURL: (OFURL *)URL | | | | | | | | > > > > > | > > | | | | | < | | | < < < < | | | | < < < < | | | | | | < < < < | | | < < < < | | | | 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 | * specified URL in the specified encoding. * * @param URL The URL to the contents for the string * @param encoding The encoding to assume * @return An initialized OFString */ - (instancetype)initWithContentsOfURL: (OFURL *)URL encoding: (OFStringEncoding)encoding; /** * @brief Writes the OFString into the specified C string with the specified * encoding. * * @param cString The C string to write into * @param maxLength The maximum number of bytes to write into the C string, * including the terminating zero * @param encoding The encoding to use for writing into the C string * @return The number of bytes written into the C string, without the * terminating zero */ - (size_t)getCString: (char *)cString maxLength: (size_t)maxLength encoding: (OFStringEncoding)encoding; /** * @brief Writes the OFString into the specified C string with the specified * encoding, replacing characters that cannot be represented in the * specified encoding with a question mark. * * @param cString The C string to write into * @param maxLength The maximum number of bytes to write into the C string, * including the terminating zero * @param encoding The encoding to use for writing into the C string * @return The number of bytes written into the C string, without the * terminating zero */ - (size_t)getLossyCString: (char *)cString maxLength: (size_t)maxLength encoding: (OFStringEncoding)encoding; /** * @brief Returns the OFString as a C string in the specified encoding. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. * * @param encoding The encoding for the C string * @return The OFString as a C string in the specified encoding */ - (const char *)cStringWithEncoding: (OFStringEncoding)encoding OF_RETURNS_INNER_POINTER; /** * @brief Returns the OFString as a C string in the specified encoding, * replacing characters that cannot be represented in the specified * encoding with a question mark. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. * * @param encoding The encoding for the C string * @return The OFString as a C string in the specified encoding */ - (const char *)lossyCStringWithEncoding: (OFStringEncoding)encoding OF_RETURNS_INNER_POINTER; /** * @brief Returns the number of bytes the string needs in the specified * encoding. * * @param encoding The encoding for the string * @return The number of bytes the string needs in the specified encoding. */ - (size_t)cStringLengthWithEncoding: (OFStringEncoding)encoding; /** * @brief Compares the string to another string. * * @param string The string to compare the string to * @return The result of the comparison */ - (OFComparisonResult)compare: (OFString *)string; /** * @brief Compares the string to another string without caring about the case. * * @param string The string to compare the string to * @return The result of the comparison */ - (OFComparisonResult)caseInsensitiveCompare: (OFString *)string; /** * @brief Returns the Unicode character at the specified index. * * @param index The index of the Unicode character to return * @return The Unicode character at the specified index */ - (OFUnichar)characterAtIndex: (size_t)index; /** * @brief Copies the Unicode characters in the specified range to the specified * buffer. * * @param buffer The buffer to store the Unicode characters * @param range The range of the Unicode characters to copy */ - (void)getCharacters: (OFUnichar *)buffer inRange: (OFRange)range; /** * @brief Returns the range of the first occurrence of the string. * * @param string The string to search * @return The range of the first occurrence of the string or a range with * `OFNotFound` as start position if it was not found */ - (OFRange)rangeOfString: (OFString *)string; /** * @brief Returns the range of the string. * * @param string The string to search * @param options Options modifying search behavior * @return The range of the first occurrence of the string or a range with * `OFNotFound` as start position if it was not found */ - (OFRange)rangeOfString: (OFString *)string options: (OFStringSearchOptions)options; /** * @brief Returns the range of the string in the specified range. * * @param string The string to search * @param options Options modifying search behaviour * @param range The range in which to search * @return The range of the first occurrence of the string or a range with * `OFNotFound` as start position if it was not found */ - (OFRange)rangeOfString: (OFString *)string options: (OFStringSearchOptions)options range: (OFRange)range; /** * @brief Returns the index of the first character from the set. * * @param characterSet The set of characters to search for * @return The index of the first occurrence of a character from the set or * `OFNotFound` if it was not found */ - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet; /** * @brief Returns the index of the first character from the set. * * @param characterSet The set of characters to search for * @param options Options modifying search behaviour * @return The index of the first occurrence of a character from the set or * `OFNotFound` if it was not found */ - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet options: (OFStringSearchOptions)options; /** * @brief Returns the index of the first character from the set. * * @param characterSet The set of characters to search for * @param options Options modifying search behaviour * @param range The range in which to search * @return The index of the first occurrence of a character from the set or * `OFNotFound` if it was not found */ - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet options: (OFStringSearchOptions)options range: (OFRange)range; /** * @brief Returns whether the string contains the specified string. * * @param string The string to search * @return Whether the string contains the specified string */ |
︙ | ︙ | |||
1022 1023 1024 1025 1026 1027 1028 | /** * @brief Creates a substring with the specified range. * * @param range The range of the substring * @return The substring as a new autoreleased OFString */ | | | 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 | /** * @brief Creates a substring with the specified range. * * @param range The range of the substring * @return The substring as a new autoreleased OFString */ - (OFString *)substringWithRange: (OFRange)range; /** * @brief The value of the string in the specified base as a `long long`. * * Leading and trailing whitespaces are ignored. * * If the string contains any non-number characters, an |
︙ | ︙ | |||
1123 1124 1125 1126 1127 1128 1129 | * * None yet * @param range The range in which to replace the string * @return A new string with the occurrences of the specified string replaced */ - (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options | | | 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 | * * None yet * @param range The range in which to replace the string * @return A new string with the occurrences of the specified string replaced */ - (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (OFRange)range; /** * @brief Checks whether the string has the specified prefix. * * @param prefix The prefix to check for * @return A boolean whether the string has the specified prefix */ |
︙ | ︙ | |||
1156 1157 1158 1159 1160 1161 1162 | componentsSeparatedByString: (OFString *)delimiter; /** * @brief Separates the string into an array of strings, split by the specified * delimiter. * * @param delimiter The delimiter for separating | | < < < < | | < < < < | | | | | < | < | > > > > > > > > > > > | > > > > > > | | > > | | | | | 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 | componentsSeparatedByString: (OFString *)delimiter; /** * @brief Separates the string into an array of strings, split by the specified * delimiter. * * @param delimiter The delimiter for separating * @param options Options according to which the string should be separated * @return An autoreleased OFArray with the separated string */ - (OFArray OF_GENERIC(OFString *) *) componentsSeparatedByString: (OFString *)delimiter options: (OFStringSeparationOptions)options; /** * @brief Separates the string into an array of strings, split by characters in * the specified set. * * @param characterSet The character set for separating * @return An autoreleased OFArray with the separated string */ - (OFArray OF_GENERIC(OFString *) *) componentsSeparatedByCharactersInSet: (OFCharacterSet *)characterSet; /** * @brief Separates the string into an array of strings, split by characters in * the specified set. * * @param characterSet The character set for separating * @param options Options according to which the string should be separated * @return An autoreleased OFArray with the separated string */ - (OFArray OF_GENERIC(OFString *) *) componentsSeparatedByCharactersInSet: (OFCharacterSet *)characterSet options: (OFStringSeparationOptions)options; /** * @brief Returns the string in UTF-16 encoding with the specified byte order. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. * * @param byteOrder The byte order for the UTF-16 encoding * @return The string in UTF-16 encoding with the specified byte order */ - (const OFChar16 *)UTF16StringWithByteOrder: (OFByteOrder)byteOrder OF_RETURNS_INNER_POINTER; /** * @brief Returns the string in UTF-32 encoding with the specified byte order. * * The result is valid until the autorelease pool is released. If you want to * use the result outside the scope of the current autorelease pool, you have to * copy it. * * @param byteOrder The byte order for the UTF-32 encoding * @return The string in UTF-32 encoding with the specified byte order */ - (const OFChar32 *)UTF32StringWithByteOrder: (OFByteOrder)byteOrder OF_RETURNS_INNER_POINTER; /** * @brief Returns the string as OFData with the specified encoding. * * @param encoding The encoding to use for the returned OFData * @return The string as OFData with the specified encoding */ - (OFData *)dataWithEncoding: (OFStringEncoding)encoding; # ifdef OF_HAVE_FILES /** * @brief Writes the string into the specified file using UTF-8 encoding. * * @param path The path of the file to write to */ - (void)writeToFile: (OFString *)path; /** * @brief Writes the string into the specified file using the specified * encoding. * * @param path The path of the file to write to * @param encoding The encoding to use to write the string into the file */ - (void)writeToFile: (OFString *)path encoding: (OFStringEncoding)encoding; # endif /** * @brief Writes the string to the specified URL using UTF-8 encoding. * * @param URL The URL to write to */ - (void)writeToURL: (OFURL *)URL; /** * @brief Writes the string to the specified URL using the specified encoding. * * @param URL The URL to write to * @param encoding The encoding to use to write the string to the URL */ - (void)writeToURL: (OFURL *)URL encoding: (OFStringEncoding)encoding; # ifdef OF_HAVE_BLOCKS /** * Enumerates all lines in the receiver using the specified block. * * @brief block The block to call for each line */ - (void)enumerateLinesUsingBlock: (OFStringLineEnumerationBlock)block; # endif @end #endif #ifdef __cplusplus extern "C" { #endif /** * @brief Parses the specified string encoding name and returns the * OFStringEncoding for it. * * Throws @ref OFInvalidArgumentException if the specified name is not a valid * encoding name. * * @param name The name to parse as a string encoding * @return The OFStringEncoding for the specified name */ extern OFStringEncoding OFStringEncodingParseName(OFString *name); /** * @brief Returns the name of the specified OFStringEncoding. * * @param encoding The encoding for which to return the name * @return The name of the specified OFStringEncoding */ extern OFString *_Nullable OFStringEncodingName(OFStringEncoding encoding); extern char *_Nullable OFStrDup(const char *_Nonnull); extern size_t OFUTF8StringEncode(OFUnichar, char *); extern ssize_t OFUTF8StringDecode(const char *, size_t, OFUnichar *); extern size_t OFUTF16StringLength(const OFChar16 *); extern size_t OFUTF32StringLength(const OFChar32 *); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END #include "OFConstantString.h" #include "OFMutableString.h" #ifdef __OBJC__ # import "OFString+CryptographicHashing.h" # import "OFString+JSONParsing.h" # ifdef OF_HAVE_FILES # import "OFString+PathAdditions.h" # endif # import "OFString+PropertyListParsing.h" # import "OFString+Serialization.h" # import "OFString+URLEncoding.h" |
︙ | ︙ |
Modified src/OFString.m from [b2cfcd4f85] to [05a5b5b79b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 35 36 37 38 39 40 41 | # include <locale.h> #endif #ifdef HAVE_XLOCALE_H # include <xlocale.h> #endif #import "OFString.h" #import "OFArray.h" #import "OFCharacterSet.h" #import "OFData.h" #import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFile.h" # import "OFFileManager.h" | > | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | # include <locale.h> #endif #ifdef HAVE_XLOCALE_H # include <xlocale.h> #endif #import "OFString.h" #import "OFASPrintF.h" #import "OFArray.h" #import "OFCharacterSet.h" #import "OFData.h" #import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFile.h" # import "OFFileManager.h" |
︙ | ︙ | |||
57 58 59 60 61 62 63 | #import "OFOpenItemFailedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFRetrieveItemAttributesFailedException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" | < | < > > > > | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | #import "OFOpenItemFailedException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFRetrieveItemAttributesFailedException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedProtocolException.h" #import "unicode.h" /* * It seems strtod is buggy on Win32. * However, the MinGW version __strtod seems to be ok. */ #ifdef __MINGW32__ # define strtod __strtod #endif #ifndef HAVE_STRTOF # define strtof strtod #endif #ifndef INFINITY # define INFINITY __builtin_inf() #endif static struct { Class isa; } placeholder; #if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L) static locale_t cLocale; #endif @interface OFString () - (size_t)of_getCString: (char *)cString maxLength: (size_t)maxLength encoding: (OFStringEncoding)encoding lossy: (bool)lossy OF_DIRECT; - (const char *)of_cStringWithEncoding: (OFStringEncoding)encoding lossy: (bool)lossy OF_DIRECT; - (OFString *) of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options depth: (size_t)depth; @end @interface OFStringPlaceholder: OFString @end extern bool OFUnicodeToISO8859_2(const OFUnichar *, unsigned char *, size_t, bool); extern bool OFUnicodeToISO8859_3(const OFUnichar *, unsigned char *, size_t, bool); extern bool OFUnicodeToISO8859_15(const OFUnichar *, unsigned char *, size_t, bool); extern bool OFUnicodeToWindows1251(const OFUnichar *, unsigned char *, size_t, bool); extern bool OFUnicodeToWindows1252(const OFUnichar *, unsigned char *, size_t, bool); extern bool OFUnicodeToCodepage437(const OFUnichar *, unsigned char *, size_t, bool); extern bool OFUnicodeToCodepage850(const OFUnichar *, unsigned char *, size_t, bool); extern bool OFUnicodeToCodepage858(const OFUnichar *, unsigned char *, size_t, bool); extern bool OFUnicodeToMacRoman(const OFUnichar *, unsigned char *, size_t, bool); extern bool OFUnicodeToKOI8R(const OFUnichar *, unsigned char *, size_t, bool); extern bool OFUnicodeToKOI8U(const OFUnichar *, unsigned char *, size_t, bool); /* References for static linking */ void _references_to_categories_of_OFString(void) { _OFString_CryptographicHashing_reference = 1; _OFString_JSONParsing_reference = 1; #ifdef OF_HAVE_FILES _OFString_PathAdditions_reference = 1; #endif _OFString_PropertyListParsing_reference = 1; _OFString_Serialization_reference = 1; _OFString_URLEncoding_reference = 1; _OFString_XMLEscaping_reference = 1; _OFString_XMLUnescaping_reference = 1; } void _reference_to_OFConstantString(void) { [OFConstantString class]; } OFStringEncoding OFStringEncodingParseName(OFString *string) { void *pool = objc_autoreleasePoolPush(); OFStringEncoding encoding; string = string.lowercaseString; if ([string isEqual: @"utf8"] || [string isEqual: @"utf-8"]) encoding = OFStringEncodingUTF8; else if ([string isEqual: @"ascii"] || [string isEqual: @"us-ascii"]) encoding = OFStringEncodingASCII; else if ([string isEqual: @"iso-8859-1"] || [string isEqual: @"iso_8859-1"]) encoding = OFStringEncodingISO8859_1; else if ([string isEqual: @"iso-8859-2"] || [string isEqual: @"iso_8859-2"]) encoding = OFStringEncodingISO8859_2; else if ([string isEqual: @"iso-8859-3"] || [string isEqual: @"iso_8859-3"]) encoding = OFStringEncodingISO8859_3; else if ([string isEqual: @"iso-8859-15"] || [string isEqual: @"iso_8859-15"]) encoding = OFStringEncodingISO8859_15; else if ([string isEqual: @"windows-1251"] || [string isEqual: @"cp1251"] || [string isEqual: @"cp-1251"] || [string isEqual: @"1251"]) encoding = OFStringEncodingWindows1251; else if ([string isEqual: @"windows-1252"] || [string isEqual: @"cp1252"] || [string isEqual: @"cp-1252"] || [string isEqual: @"1252"]) encoding = OFStringEncodingWindows1252; else if ([string isEqual: @"cp437"] || [string isEqual: @"cp-437"] || [string isEqual: @"ibm437"] || [string isEqual: @"437"]) encoding = OFStringEncodingCodepage437; else if ([string isEqual: @"cp850"] || [string isEqual: @"cp-850"] || [string isEqual: @"ibm850"] || [string isEqual: @"850"]) encoding = OFStringEncodingCodepage850; else if ([string isEqual: @"cp858"] || [string isEqual: @"cp-858"] || [string isEqual: @"ibm858"] || [string isEqual: @"858"]) encoding = OFStringEncodingCodepage858; else if ([string isEqual: @"macintosh"] || [string isEqual: @"mac"]) encoding = OFStringEncodingMacRoman; else if ([string isEqual: @"koi8-r"]) encoding = OFStringEncodingKOI8R; else if ([string isEqual: @"koi8-u"]) encoding = OFStringEncodingKOI8U; else @throw [OFInvalidArgumentException exception]; objc_autoreleasePoolPop(pool); return encoding; } OFString * OFStringEncodingName(OFStringEncoding encoding) { switch (encoding) { case OFStringEncodingUTF8: return @"UTF-8"; case OFStringEncodingASCII: return @"ASCII"; case OFStringEncodingISO8859_1: return @"ISO 8859-1"; case OFStringEncodingISO8859_2: return @"ISO 8859-2"; case OFStringEncodingISO8859_3: return @"ISO 8859-3"; case OFStringEncodingISO8859_15: return @"ISO 8859-15"; case OFStringEncodingWindows1251: return @"Windows-1251"; case OFStringEncodingWindows1252: return @"Windows-1252"; case OFStringEncodingCodepage437: return @"Codepage 437"; case OFStringEncodingCodepage850: return @"Codepage 850"; case OFStringEncodingCodepage858: return @"Codepage 858"; case OFStringEncodingMacRoman: return @"Mac Roman"; case OFStringEncodingKOI8R: return @"KOI8-R"; case OFStringEncodingKOI8U: return @"KOI8-U"; case OFStringEncodingAutodetect: return @"autodetect"; } return nil; } size_t OFUTF8StringEncode(OFUnichar character, char *buffer) { if (character < 0x80) { buffer[0] = character; return 1; } else if (character < 0x800) { buffer[0] = 0xC0 | (character >> 6); buffer[1] = 0x80 | (character & 0x3F); |
︙ | ︙ | |||
261 262 263 264 265 266 267 | return 4; } return 0; } ssize_t | | | 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | return 4; } return 0; } ssize_t OFUTF8StringDecode(const char *buffer_, size_t length, OFUnichar *ret) { const unsigned char *buffer = (const unsigned char *)buffer_; if (!(*buffer & 0x80)) { *ret = buffer[0]; return 1; } |
︙ | ︙ | |||
311 312 313 314 315 316 317 | return 4; } return 0; } size_t | | | > > > > > > > > > > | | | < | < | 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 | return 4; } return 0; } size_t OFUTF16StringLength(const OFChar16 *string) { size_t length = 0; while (*string++ != 0) length++; return length; } size_t OFUTF32StringLength(const OFChar32 *string) { size_t length = 0; while (*string++ != 0) length++; return length; } char * OFStrDup(const char *string) { size_t length = strlen(string); char *copy = (char *)OFAllocMemory(1, length + 1); memcpy(copy, string, length + 1); return copy; } #ifdef OF_HAVE_UNICODE_TABLES static OFString * decomposedString(OFString *self, const char *const *const *table, size_t size) { OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); const OFUnichar *characters = self.characters; size_t length = self.length; for (size_t i = 0; i < length; i++) { OFUnichar c = characters[i]; const char *const *page; if (c >= size) { [ret appendCharacters: &c length: 1]; continue; } page = table[c >> 8]; if (page != NULL && page[c & 0xFF] != NULL) [ret appendUTF8String: page[c & 0xFF]]; else [ret appendCharacters: &c length: 1]; } objc_autoreleasePoolPop(pool); return ret; } #endif |
︙ | ︙ | |||
378 379 380 381 382 383 384 | - (instancetype)initWithUTF8String: (const char *)UTF8String { OFUTF8String *string; size_t length; void *storage; length = strlen(UTF8String); | | | | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 | - (instancetype)initWithUTF8String: (const char *)UTF8String { OFUTF8String *string; size_t length; void *storage; length = strlen(UTF8String); string = OFAllocObject([OFUTF8String class], length + 1, 1, &storage); return (id)[string of_initWithUTF8String: UTF8String length: length storage: storage]; } - (instancetype)initWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength { OFUTF8String *string; void *storage; string = OFAllocObject([OFUTF8String class], UTF8StringLength + 1, 1, &storage); return (id)[string of_initWithUTF8String: UTF8String length: UTF8StringLength storage: storage]; } |
︙ | ︙ | |||
418 419 420 421 422 423 424 | return (id)[[OFUTF8String alloc] initWithUTF8StringNoCopy: UTF8String length: UTF8StringLength freeWhenDone: freeWhenDone]; } - (instancetype)initWithCString: (const char *)cString | | | | | | | | | | | | | | | | | | | | | | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 | return (id)[[OFUTF8String alloc] initWithUTF8StringNoCopy: UTF8String length: UTF8StringLength freeWhenDone: freeWhenDone]; } - (instancetype)initWithCString: (const char *)cString encoding: (OFStringEncoding)encoding { if (encoding == OFStringEncodingUTF8) { OFUTF8String *string; size_t length; void *storage; length = strlen(cString); string = OFAllocObject([OFUTF8String class], length + 1, 1, &storage); return (id)[string of_initWithUTF8String: cString length: length storage: storage]; } return (id)[[OFUTF8String alloc] initWithCString: cString encoding: encoding]; } - (instancetype)initWithCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength { if (encoding == OFStringEncodingUTF8) { OFUTF8String *string; void *storage; string = OFAllocObject([OFUTF8String class], cStringLength + 1, 1, &storage); return (id)[string of_initWithUTF8String: cString length: cStringLength storage: storage]; } return (id)[[OFUTF8String alloc] initWithCString: cString encoding: encoding length: cStringLength]; } - (instancetype)initWithData: (OFData *)data encoding: (OFStringEncoding)encoding { return (id)[[OFUTF8String alloc] initWithData: data encoding: encoding]; } - (instancetype)initWithString: (OFString *)string { return (id)[[OFUTF8String alloc] initWithString: string]; } - (instancetype)initWithCharacters: (const OFUnichar *)string length: (size_t)length { return (id)[[OFUTF8String alloc] initWithCharacters: string length: length]; } - (instancetype)initWithUTF16String: (const OFChar16 *)string { return (id)[[OFUTF8String alloc] initWithUTF16String: string]; } - (instancetype)initWithUTF16String: (const OFChar16 *)string length: (size_t)length { return (id)[[OFUTF8String alloc] initWithUTF16String: string length: length]; } - (instancetype)initWithUTF16String: (const OFChar16 *)string byteOrder: (OFByteOrder)byteOrder { return (id)[[OFUTF8String alloc] initWithUTF16String: string byteOrder: byteOrder]; } - (instancetype)initWithUTF16String: (const OFChar16 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder { return (id)[[OFUTF8String alloc] initWithUTF16String: string length: length byteOrder: byteOrder]; } - (instancetype)initWithUTF32String: (const OFChar32 *)string { return (id)[[OFUTF8String alloc] initWithUTF32String: string]; } - (instancetype)initWithUTF32String: (const OFChar32 *)string length: (size_t)length { return (id)[[OFUTF8String alloc] initWithUTF32String: string length: length]; } - (instancetype)initWithUTF32String: (const OFChar32 *)string byteOrder: (OFByteOrder)byteOrder { return (id)[[OFUTF8String alloc] initWithUTF32String: string byteOrder: byteOrder]; } - (instancetype)initWithUTF32String: (const OFChar32 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder { return (id)[[OFUTF8String alloc] initWithUTF32String: string length: length byteOrder: byteOrder]; } - (instancetype)initWithFormat: (OFConstantString *)format, ... |
︙ | ︙ | |||
561 562 563 564 565 566 567 | #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path { return (id)[[OFUTF8String alloc] initWithContentsOfFile: path]; } - (instancetype)initWithContentsOfFile: (OFString *)path | | < | < | 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 | #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path { return (id)[[OFUTF8String alloc] initWithContentsOfFile: path]; } - (instancetype)initWithContentsOfFile: (OFString *)path encoding: (OFStringEncoding)encoding { return (id)[[OFUTF8String alloc] initWithContentsOfFile: path encoding: encoding]; } #endif - (instancetype)initWithContentsOfURL: (OFURL *)URL { return (id)[[OFUTF8String alloc] initWithContentsOfURL: URL]; } - (instancetype)initWithContentsOfURL: (OFURL *)URL encoding: (OFStringEncoding)encoding { return (id)[[OFUTF8String alloc] initWithContentsOfURL: URL encoding: encoding]; } - (instancetype)initWithSerialization: (OFXMLElement *)element { return (id)[[OFUTF8String alloc] initWithSerialization: element]; } - (instancetype)retain |
︙ | ︙ | |||
667 668 669 670 671 672 673 | return [[[self alloc] initWithUTF8StringNoCopy: UTF8String length: UTF8StringLength freeWhenDone: freeWhenDone] autorelease]; } + (instancetype)stringWithCString: (const char *)cString | | | | | | | | | | | | | | | | | | 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 | return [[[self alloc] initWithUTF8StringNoCopy: UTF8String length: UTF8StringLength freeWhenDone: freeWhenDone] autorelease]; } + (instancetype)stringWithCString: (const char *)cString encoding: (OFStringEncoding)encoding { return [[[self alloc] initWithCString: cString encoding: encoding] autorelease]; } + (instancetype)stringWithCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength { return [[[self alloc] initWithCString: cString encoding: encoding length: cStringLength] autorelease]; } + (instancetype)stringWithData: (OFData *)data encoding: (OFStringEncoding)encoding { return [[[self alloc] initWithData: data encoding: encoding] autorelease]; } + (instancetype)stringWithString: (OFString *)string { return [[[self alloc] initWithString: string] autorelease]; } + (instancetype)stringWithCharacters: (const OFUnichar *)string length: (size_t)length { return [[[self alloc] initWithCharacters: string length: length] autorelease]; } + (instancetype)stringWithUTF16String: (const OFChar16 *)string { return [[[self alloc] initWithUTF16String: string] autorelease]; } + (instancetype)stringWithUTF16String: (const OFChar16 *)string length: (size_t)length { return [[[self alloc] initWithUTF16String: string length: length] autorelease]; } + (instancetype)stringWithUTF16String: (const OFChar16 *)string byteOrder: (OFByteOrder)byteOrder { return [[[self alloc] initWithUTF16String: string byteOrder: byteOrder] autorelease]; } + (instancetype)stringWithUTF16String: (const OFChar16 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder { return [[[self alloc] initWithUTF16String: string length: length byteOrder: byteOrder] autorelease]; } + (instancetype)stringWithUTF32String: (const OFChar32 *)string { return [[[self alloc] initWithUTF32String: string] autorelease]; } + (instancetype)stringWithUTF32String: (const OFChar32 *)string length: (size_t)length { return [[[self alloc] initWithUTF32String: string length: length] autorelease]; } + (instancetype)stringWithUTF32String: (const OFChar32 *)string byteOrder: (OFByteOrder)byteOrder { return [[[self alloc] initWithUTF32String: string byteOrder: byteOrder] autorelease]; } + (instancetype)stringWithUTF32String: (const OFChar32 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder { return [[[self alloc] initWithUTF32String: string length: length byteOrder: byteOrder] autorelease]; } + (instancetype)stringWithFormat: (OFConstantString *)format, ... |
︙ | ︙ | |||
777 778 779 780 781 782 783 | #ifdef OF_HAVE_FILES + (instancetype)stringWithContentsOfFile: (OFString *)path { return [[[self alloc] initWithContentsOfFile: path] autorelease]; } + (instancetype)stringWithContentsOfFile: (OFString *)path | | < | < | | | < < < | | < | < < < < | | < | | | | 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 | #ifdef OF_HAVE_FILES + (instancetype)stringWithContentsOfFile: (OFString *)path { return [[[self alloc] initWithContentsOfFile: path] autorelease]; } + (instancetype)stringWithContentsOfFile: (OFString *)path encoding: (OFStringEncoding)encoding { return [[[self alloc] initWithContentsOfFile: path encoding: encoding] autorelease]; } #endif + (instancetype)stringWithContentsOfURL: (OFURL *)URL { return [[[self alloc] initWithContentsOfURL: URL] autorelease]; } + (instancetype)stringWithContentsOfURL: (OFURL *)URL encoding: (OFStringEncoding)encoding { return [[[self alloc] initWithContentsOfURL: URL encoding: encoding] autorelease]; } - (instancetype)init { if ([self isMemberOfClass: [OFString class]]) { @try { [self doesNotRecognizeSelector: _cmd]; } @catch (id e) { [self release]; @throw e; } abort(); } return [super init]; } - (instancetype)initWithUTF8String: (const char *)UTF8String { return [self initWithCString: UTF8String encoding: OFStringEncodingUTF8 length: strlen(UTF8String)]; } - (instancetype)initWithUTF8String: (const char *)UTF8String length: (size_t)UTF8StringLength { return [self initWithCString: UTF8String encoding: OFStringEncodingUTF8 length: UTF8StringLength]; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String freeWhenDone: (bool)freeWhenDone { id ret = [self initWithUTF8String: UTF8String]; if (freeWhenDone) OFFreeMemory(UTF8String); return ret; } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { id ret = [self initWithUTF8String: UTF8String length: UTF8StringLength]; if (freeWhenDone) OFFreeMemory(UTF8String); return ret; } - (instancetype)initWithCString: (const char *)cString encoding: (OFStringEncoding)encoding { return [self initWithCString: cString encoding: encoding length: strlen(cString)]; } - (instancetype)initWithCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength { OF_INVALID_INIT_METHOD } - (instancetype)initWithData: (OFData *)data encoding: (OFStringEncoding)encoding { @try { if (data.itemSize != 1) @throw [OFInvalidArgumentException exception]; } @catch (id e) { [self release]; @throw e; |
︙ | ︙ | |||
899 900 901 902 903 904 905 | } - (instancetype)initWithString: (OFString *)string { OF_INVALID_INIT_METHOD } | | | | | | | | | | | | | | | | | | | | | | | < | | | 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 | } - (instancetype)initWithString: (OFString *)string { OF_INVALID_INIT_METHOD } - (instancetype)initWithCharacters: (const OFUnichar *)string length: (size_t)length { OF_INVALID_INIT_METHOD } - (instancetype)initWithUTF16String: (const OFChar16 *)string { return [self initWithUTF16String: string length: OFUTF16StringLength(string) byteOrder: OFByteOrderNative]; } - (instancetype)initWithUTF16String: (const OFChar16 *)string length: (size_t)length { return [self initWithUTF16String: string length: length byteOrder: OFByteOrderNative]; } - (instancetype)initWithUTF16String: (const OFChar16 *)string byteOrder: (OFByteOrder)byteOrder { return [self initWithUTF16String: string length: OFUTF16StringLength(string) byteOrder: byteOrder]; } - (instancetype)initWithUTF16String: (const OFChar16 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder { OF_INVALID_INIT_METHOD } - (instancetype)initWithUTF32String: (const OFChar32 *)string { return [self initWithUTF32String: string length: OFUTF32StringLength(string) byteOrder: OFByteOrderNative]; } - (instancetype)initWithUTF32String: (const OFChar32 *)string length: (size_t)length { return [self initWithUTF32String: string length: length byteOrder: OFByteOrderNative]; } - (instancetype)initWithUTF32String: (const OFChar32 *)string byteOrder: (OFByteOrder)byteOrder { return [self initWithUTF32String: string length: OFUTF32StringLength(string) byteOrder: byteOrder]; } - (instancetype)initWithUTF32String: (const OFChar32 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder { OF_INVALID_INIT_METHOD } - (instancetype)initWithFormat: (OFConstantString *)format, ... { id ret; va_list arguments; va_start(arguments, format); ret = [self initWithFormat: format arguments: arguments]; va_end(arguments); return ret; } - (instancetype)initWithFormat: (OFConstantString *)format arguments: (va_list)arguments { OF_INVALID_INIT_METHOD } #ifdef OF_HAVE_FILES - (instancetype)initWithContentsOfFile: (OFString *)path { return [self initWithContentsOfFile: path encoding: OFStringEncodingUTF8]; } - (instancetype)initWithContentsOfFile: (OFString *)path encoding: (OFStringEncoding)encoding { char *tmp; unsigned long long fileSize; @try { void *pool = objc_autoreleasePoolPush(); OFFile *file = nil; |
︙ | ︙ | |||
1025 1026 1027 1028 1029 1030 1031 | /* * We need one extra byte for the terminating zero if we want * to use -[initWithUTF8StringNoCopy:length:freeWhenDone:]. */ if (SIZE_MAX - (size_t)fileSize < 1) @throw [OFOutOfRangeException exception]; | | | < < | | > | | | > > > > | | | | | 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 | /* * We need one extra byte for the terminating zero if we want * to use -[initWithUTF8StringNoCopy:length:freeWhenDone:]. */ if (SIZE_MAX - (size_t)fileSize < 1) @throw [OFOutOfRangeException exception]; tmp = OFAllocMemory((size_t)fileSize + 1, 1); @try { file = [[OFFile alloc] initWithPath: path mode: @"r"]; [file readIntoBuffer: tmp exactLength: (size_t)fileSize]; } @catch (id e) { OFFreeMemory(tmp); @throw e; } @finally { [file release]; } tmp[(size_t)fileSize] = '\0'; } @catch (id e) { [self release]; @throw e; } if (encoding == OFStringEncodingUTF8) { @try { self = [self initWithUTF8StringNoCopy: tmp length: (size_t)fileSize freeWhenDone: true]; } @catch (id e) { OFFreeMemory(tmp); @throw e; } } else { @try { self = [self initWithCString: tmp encoding: encoding length: (size_t)fileSize]; } @finally { OFFreeMemory(tmp); } } return self; } #endif - (instancetype)initWithContentsOfURL: (OFURL *)URL { return [self initWithContentsOfURL: URL encoding: OFStringEncodingAutodetect]; } - (instancetype)initWithContentsOfURL: (OFURL *)URL encoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); OFData *data; @try { data = [OFData dataWithContentsOfURL: URL]; } @catch (id e) { |
︙ | ︙ | |||
1097 1098 1099 1100 1101 1102 1103 | - (instancetype)initWithSerialization: (OFXMLElement *)element { void *pool = objc_autoreleasePoolPush(); OFString *stringValue; @try { | | | 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 | - (instancetype)initWithSerialization: (OFXMLElement *)element { void *pool = objc_autoreleasePoolPush(); OFString *stringValue; @try { if (![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; if ([self isKindOfClass: [OFMutableString class]]) { if (![element.name isEqual: @"OFMutableString"]) @throw [OFInvalidArgumentException exception]; } else { if (![element.name isEqual: @"OFString"]) |
︙ | ︙ | |||
1123 1124 1125 1126 1127 1128 1129 | objc_autoreleasePoolPop(pool); return self; } - (size_t)of_getCString: (char *)cString maxLength: (size_t)maxLength | | | | | < | 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 | objc_autoreleasePoolPop(pool); return self; } - (size_t)of_getCString: (char *)cString maxLength: (size_t)maxLength encoding: (OFStringEncoding)encoding lossy: (bool)lossy { const OFUnichar *characters = self.characters; size_t i, length = self.length; switch (encoding) { case OFStringEncodingUTF8:; size_t j = 0; for (i = 0; i < length; i++) { char buffer[4]; size_t len = OFUTF8StringEncode(characters[i], buffer); /* * Check for one more than the current index, as we * need one for the terminating zero. */ if (j + len >= maxLength) @throw [OFOutOfRangeException exception]; |
︙ | ︙ | |||
1167 1168 1169 1170 1171 1172 1173 | break; } } cString[j] = '\0'; return j; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > > | | < | | > | | | > > > | > < | | | | | | | | | | | | | | | > | | | | > > > | > > > > > > > > > > | | | < | | < | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | < | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 | break; } } cString[j] = '\0'; return j; case OFStringEncodingASCII: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; for (i = 0; i < length; i++) { if OF_UNLIKELY (characters[i] > 0x80) { if (lossy) cString[i] = '?'; else @throw [OFInvalidEncodingException exception]; } else cString[i] = (unsigned char)characters[i]; } cString[i] = '\0'; return length; case OFStringEncodingISO8859_1: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; for (i = 0; i < length; i++) { if OF_UNLIKELY (characters[i] > 0xFF) { if (lossy) cString[i] = '?'; else @throw [OFInvalidEncodingException exception]; } else cString[i] = (unsigned char)characters[i]; } cString[i] = '\0'; return length; #ifdef HAVE_ISO_8859_2 case OFStringEncodingISO8859_2: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; if (!OFUnicodeToISO8859_2(characters, (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; return length; #endif #ifdef HAVE_ISO_8859_3 case OFStringEncodingISO8859_3: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; if (!OFUnicodeToISO8859_3(characters, (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; return length; #endif #ifdef HAVE_ISO_8859_15 case OFStringEncodingISO8859_15: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; if (!OFUnicodeToISO8859_15(characters, (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; return length; #endif #ifdef HAVE_WINDOWS_1251 case OFStringEncodingWindows1251: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; if (!OFUnicodeToWindows1251(characters, (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; return length; #endif #ifdef HAVE_WINDOWS_1252 case OFStringEncodingWindows1252: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; if (!OFUnicodeToWindows1252(characters, (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; return length; #endif #ifdef HAVE_CODEPAGE_437 case OFStringEncodingCodepage437: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; if (!OFUnicodeToCodepage437(characters, (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; return length; #endif #ifdef HAVE_CODEPAGE_850 case OFStringEncodingCodepage850: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; if (!OFUnicodeToCodepage850(characters, (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; return length; #endif #ifdef HAVE_CODEPAGE_858 case OFStringEncodingCodepage858: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; if (!OFUnicodeToCodepage858(characters, (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; return length; #endif #ifdef HAVE_MAC_ROMAN case OFStringEncodingMacRoman: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; if (!OFUnicodeToMacRoman(characters, (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; return length; #endif #ifdef HAVE_KOI8_R case OFStringEncodingKOI8R: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; if (!OFUnicodeToKOI8R(characters, (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; return length; #endif #ifdef HAVE_KOI8_U case OFStringEncodingKOI8U: if (length + 1 > maxLength) @throw [OFOutOfRangeException exception]; if (!OFUnicodeToKOI8U(characters, (unsigned char *)cString, length, lossy)) @throw [OFInvalidEncodingException exception]; cString[length] = '\0'; return length; #endif default: @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; } } - (size_t)getCString: (char *)cString maxLength: (size_t)maxLength encoding: (OFStringEncoding)encoding { return [self of_getCString: cString maxLength: maxLength encoding: encoding lossy: false]; } - (size_t)getLossyCString: (char *)cString maxLength: (size_t)maxLength encoding: (OFStringEncoding)encoding { return [self of_getCString: cString maxLength: maxLength encoding: encoding lossy: true]; } - (const char *)of_cStringWithEncoding: (OFStringEncoding)encoding lossy: (bool)lossy { size_t length = self.length; char *cString; size_t cStringLength; const char *ret; switch (encoding) { case OFStringEncodingUTF8: cString = OFAllocMemory((length * 4) + 1, 1); @try { cStringLength = [self of_getCString: cString maxLength: (length * 4) + 1 encoding: OFStringEncodingUTF8 lossy: lossy]; } @catch (id e) { OFFreeMemory(cString); @throw e; } @try { cString = OFResizeMemory(cString, cStringLength + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } break; case OFStringEncodingASCII: case OFStringEncodingISO8859_1: case OFStringEncodingISO8859_2: case OFStringEncodingISO8859_3: case OFStringEncodingISO8859_15: case OFStringEncodingWindows1251: case OFStringEncodingWindows1252: case OFStringEncodingCodepage437: case OFStringEncodingCodepage850: case OFStringEncodingCodepage858: case OFStringEncodingMacRoman: case OFStringEncodingKOI8R: case OFStringEncodingKOI8U: cString = OFAllocMemory(length + 1, 1); @try { cStringLength = [self of_getCString: cString maxLength: length + 1 encoding: encoding lossy: lossy]; } @catch (id e) { OFFreeMemory(cString); @throw e; } break; default: @throw [OFInvalidEncodingException exception]; } @try { ret = [[OFData dataWithItemsNoCopy: cString count: cStringLength + 1 freeWhenDone: true] items]; } @catch (id e) { OFFreeMemory(cString); @throw e; } return ret; } - (const char *)cStringWithEncoding: (OFStringEncoding)encoding { return [self of_cStringWithEncoding: encoding lossy: false]; } - (const char *)lossyCStringWithEncoding: (OFStringEncoding)encoding { return [self of_cStringWithEncoding: encoding lossy: true]; } - (const char *)UTF8String { return [self cStringWithEncoding: OFStringEncodingUTF8]; } - (size_t)length { OF_UNRECOGNIZED_SELECTOR } - (size_t)cStringLengthWithEncoding: (OFStringEncoding)encoding { switch (encoding) { case OFStringEncodingUTF8:; const OFUnichar *characters; size_t length, UTF8StringLength = 0; characters = self.characters; length = self.length; for (size_t i = 0; i < length; i++) { char buffer[4]; size_t len = OFUTF8StringEncode(characters[i], buffer); if (len == 0) @throw [OFInvalidEncodingException exception]; UTF8StringLength += len; } return UTF8StringLength; case OFStringEncodingASCII: case OFStringEncodingISO8859_1: case OFStringEncodingISO8859_2: case OFStringEncodingISO8859_3: case OFStringEncodingISO8859_15: case OFStringEncodingWindows1251: case OFStringEncodingWindows1252: case OFStringEncodingCodepage437: case OFStringEncodingCodepage850: case OFStringEncodingCodepage858: case OFStringEncodingMacRoman: case OFStringEncodingKOI8R: case OFStringEncodingKOI8U: return self.length; default: @throw [OFInvalidEncodingException exception]; } } - (size_t)UTF8StringLength { return [self cStringLengthWithEncoding: OFStringEncodingUTF8]; } - (OFUnichar)characterAtIndex: (size_t)idx { OF_UNRECOGNIZED_SELECTOR } - (void)getCharacters: (OFUnichar *)buffer inRange: (OFRange)range { for (size_t i = 0; i < range.length; i++) buffer[i] = [self characterAtIndex: range.location + i]; } - (bool)isEqual: (id)object { void *pool; OFString *string; const OFUnichar *characters, *otherCharacters; size_t length; if (object == self) return true; if (![object isKindOfClass: [OFString class]]) return false; string = object; length = self.length; if (string.length != length) return false; pool = objc_autoreleasePoolPush(); characters = self.characters; otherCharacters = string.characters; if (memcmp(characters, otherCharacters, length * sizeof(OFUnichar)) != 0) { objc_autoreleasePoolPop(pool); return false; } objc_autoreleasePoolPop(pool); return true; } - (id)copy { return [self retain]; } - (id)mutableCopy { return [[OFMutableString alloc] initWithString: self]; } - (OFComparisonResult)compare: (OFString *)string { void *pool; const OFUnichar *characters, *otherCharacters; size_t minimumLength; if (string == self) return OFOrderedSame; if (![string isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; minimumLength = (self.length > string.length ? string.length : self.length); pool = objc_autoreleasePoolPush(); characters = self.characters; otherCharacters = string.characters; for (size_t i = 0; i < minimumLength; i++) { if (characters[i] > otherCharacters[i]) { objc_autoreleasePoolPop(pool); return OFOrderedDescending; } if (characters[i] < otherCharacters[i]) { objc_autoreleasePoolPop(pool); return OFOrderedAscending; } } objc_autoreleasePoolPop(pool); if (self.length > string.length) return OFOrderedDescending; if (self.length < string.length) return OFOrderedAscending; return OFOrderedSame; } - (OFComparisonResult)caseInsensitiveCompare: (OFString *)string { void *pool = objc_autoreleasePoolPush(); const OFUnichar *characters, *otherCharacters; size_t length, otherLength, minimumLength; if (string == self) return OFOrderedSame; characters = self.characters; otherCharacters = string.characters; length = self.length; otherLength = string.length; minimumLength = (length > otherLength ? otherLength : length); for (size_t i = 0; i < minimumLength; i++) { OFUnichar c = characters[i]; OFUnichar oc = otherCharacters[i]; #ifdef OF_HAVE_UNICODE_TABLES if (c >> 8 < OFUnicodeCaseFoldingTableSize) { OFUnichar tc = OFUnicodeCaseFoldingTable[c >> 8][c & 0xFF]; if (tc) c = tc; } if (oc >> 8 < OFUnicodeCaseFoldingTableSize) { OFUnichar tc = OFUnicodeCaseFoldingTable[oc >> 8][oc & 0xFF]; if (tc) oc = tc; } #else c = OFASCIIToUpper(c); oc = OFASCIIToUpper(oc); #endif if (c > oc) { objc_autoreleasePoolPop(pool); return OFOrderedDescending; } if (c < oc) { objc_autoreleasePoolPop(pool); return OFOrderedAscending; } } objc_autoreleasePoolPop(pool); if (length > otherLength) return OFOrderedDescending; if (length < otherLength) return OFOrderedAscending; return OFOrderedSame; } - (unsigned long)hash { const OFUnichar *characters = self.characters; size_t length = self.length; unsigned long hash; OFHashInit(&hash); for (size_t i = 0; i < length; i++) { const OFUnichar c = characters[i]; OFHashAdd(&hash, (c & 0xFF0000) >> 16); OFHashAdd(&hash, (c & 0x00FF00) >> 8); OFHashAdd(&hash, c & 0x0000FF); } OFHashFinalize(&hash); return hash; } - (OFString *)description { return [[self copy] autorelease]; |
︙ | ︙ | |||
1693 1694 1695 1696 1697 1698 1699 | if ([self isKindOfClass: [OFMutableString class]]) className = @"OFMutableString"; else className = @"OFString"; element = [OFXMLElement elementWithName: className | | | < | > | < | > | | < | < | < | < | < | < | | < | | | < | < < | < < | | < < | < | | < < | < | < | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | < | | | | | | | | | 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 | if ([self isKindOfClass: [OFMutableString class]]) className = @"OFMutableString"; else className = @"OFString"; element = [OFXMLElement elementWithName: className namespace: OFSerializationNS stringValue: self]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } - (OFString *)JSONRepresentation { return [self of_JSONRepresentationWithOptions: 0 depth: 0]; } - (OFString *)JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options { return [self of_JSONRepresentationWithOptions: options depth: 0]; } - (OFString *) of_JSONRepresentationWithOptions: (OFJSONRepresentationOptions)options depth: (size_t)depth { OFMutableString *JSON = [[self mutableCopy] autorelease]; /* FIXME: This is slow! Write it in pure C! */ [JSON replaceOccurrencesOfString: @"\\" withString: @"\\\\"]; [JSON replaceOccurrencesOfString: @"\"" withString: @"\\\""]; [JSON replaceOccurrencesOfString: @"\b" withString: @"\\b"]; [JSON replaceOccurrencesOfString: @"\f" withString: @"\\f"]; [JSON replaceOccurrencesOfString: @"\r" withString: @"\\r"]; [JSON replaceOccurrencesOfString: @"\t" withString: @"\\t"]; if (options & OFJSONRepresentationOptionJSON5) { [JSON replaceOccurrencesOfString: @"\n" withString: @"\\\n"]; if (options & OFJSONRepresentationOptionIsIdentifier) { const char *cString = self.UTF8String; if ((!OFASCIIIsAlpha(cString[0]) && cString[0] != '_' && cString[0] != '$') || strpbrk(cString, " \n\r\t\b\f\\\"'") != NULL) { [JSON prependString: @"\""]; [JSON appendString: @"\""]; } } else { [JSON prependString: @"\""]; [JSON appendString: @"\""]; } } else { [JSON replaceOccurrencesOfString: @"\n" withString: @"\\n"]; [JSON prependString: @"\""]; [JSON appendString: @"\""]; } [JSON makeImmutable]; return JSON; } - (OFData *)messagePackRepresentation { OFMutableData *data; size_t length; length = self.UTF8StringLength; if (length <= 31) { uint8_t tmp = 0xA0 | ((uint8_t)length & 0x1F); data = [OFMutableData dataWithCapacity: length + 1]; [data addItem: &tmp]; } else if (length <= UINT8_MAX) { uint8_t type = 0xD9; uint8_t tmp = (uint8_t)length; data = [OFMutableData dataWithCapacity: length + 2]; [data addItem: &type]; [data addItem: &tmp]; } else if (length <= UINT16_MAX) { uint8_t type = 0xDA; uint16_t tmp = OFToBigEndian16((uint16_t)length); data = [OFMutableData dataWithCapacity: length + 3]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else if (length <= UINT32_MAX) { uint8_t type = 0xDB; uint32_t tmp = OFToBigEndian32((uint32_t)length); data = [OFMutableData dataWithCapacity: length + 5]; [data addItem: &type]; [data addItems: &tmp count: sizeof(tmp)]; } else @throw [OFOutOfRangeException exception]; [data addItems: self.UTF8String count: length]; return data; } - (OFRange)rangeOfString: (OFString *)string { return [self rangeOfString: string options: 0 range: OFRangeMake(0, self.length)]; } - (OFRange)rangeOfString: (OFString *)string options: (OFStringSearchOptions)options { return [self rangeOfString: string options: options range: OFRangeMake(0, self.length)]; } - (OFRange)rangeOfString: (OFString *)string options: (OFStringSearchOptions)options range: (OFRange)range { void *pool; const OFUnichar *searchCharacters; OFUnichar *characters; size_t searchLength; if ((searchLength = string.length) == 0) return OFRangeMake(0, 0); if (searchLength > range.length) return OFRangeMake(OFNotFound, 0); if (range.length > SIZE_MAX / sizeof(OFUnichar)) @throw [OFOutOfRangeException exception]; pool = objc_autoreleasePoolPush(); searchCharacters = string.characters; characters = OFAllocMemory(range.length, sizeof(OFUnichar)); @try { [self getCharacters: characters inRange: range]; if (options & OFStringSearchBackwards) { for (size_t i = range.length - searchLength;; i--) { if (memcmp(characters + i, searchCharacters, searchLength * sizeof(OFUnichar)) == 0) { objc_autoreleasePoolPop(pool); return OFRangeMake(range.location + i, searchLength); } /* No match and we're at the last character */ if (i == 0) break; } } else { for (size_t i = 0; i <= range.length - searchLength; i++) { if (memcmp(characters + i, searchCharacters, searchLength * sizeof(OFUnichar)) == 0) { objc_autoreleasePoolPop(pool); return OFRangeMake(range.location + i, searchLength); } } } } @finally { OFFreeMemory(characters); } objc_autoreleasePoolPop(pool); return OFRangeMake(OFNotFound, 0); } - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet { return [self indexOfCharacterFromSet: characterSet options: 0 range: OFRangeMake(0, self.length)]; } - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet options: (OFStringSearchOptions)options { return [self indexOfCharacterFromSet: characterSet options: options range: OFRangeMake(0, self.length)]; } - (size_t)indexOfCharacterFromSet: (OFCharacterSet *)characterSet options: (OFStringSearchOptions)options range: (OFRange)range { bool (*characterIsMember)(id, SEL, OFUnichar) = (bool (*)(id, SEL, OFUnichar))[characterSet methodForSelector: @selector(characterIsMember:)]; OFUnichar *characters; if (range.length == 0) return OFNotFound; if (range.length > SIZE_MAX / sizeof(OFUnichar)) @throw [OFOutOfRangeException exception]; characters = OFAllocMemory(range.length, sizeof(OFUnichar)); @try { [self getCharacters: characters inRange: range]; if (options & OFStringSearchBackwards) { for (size_t i = range.length - 1;; i--) { if (characterIsMember(characterSet, @selector(characterIsMember:), characters[i])) return range.location + i; /* No match and we're at the last character */ if (i == 0) break; } } else { for (size_t i = 0; i < range.length; i++) if (characterIsMember(characterSet, @selector(characterIsMember:), characters[i])) return range.location + i; } } @finally { OFFreeMemory(characters); } return OFNotFound; } - (bool)containsString: (OFString *)string { void *pool; const OFUnichar *characters, *searchCharacters; size_t length, searchLength; if ((searchLength = string.length) == 0) return true; if (searchLength > (length = self.length)) return false; pool = objc_autoreleasePoolPush(); characters = self.characters; searchCharacters = string.characters; for (size_t i = 0; i <= length - searchLength; i++) { if (memcmp(characters + i, searchCharacters, searchLength * sizeof(OFUnichar)) == 0) { objc_autoreleasePoolPop(pool); return true; } } objc_autoreleasePoolPop(pool); return false; } - (OFString *)substringFromIndex: (size_t)idx { return [self substringWithRange: OFRangeMake(idx, self.length - idx)]; } - (OFString *)substringToIndex: (size_t)idx { return [self substringWithRange: OFRangeMake(0, idx)]; } - (OFString *)substringWithRange: (OFRange)range { void *pool; OFString *ret; if (range.length > SIZE_MAX - range.location || range.location + range.length > self.length) @throw [OFOutOfRangeException exception]; |
︙ | ︙ | |||
2027 2028 2029 2030 2031 2032 2033 | - (OFString *)stringByAppendingFormat: (OFConstantString *)format, ... { OFString *ret; va_list arguments; va_start(arguments, format); | | < < < | | < < < < < < < | < < < | < < < < < < < < < < < < < < < < < < < < < | < | | < | | | | < | | | | | < | | | | > > > > > > > | | > | | | | | | | | | | > > | > > > > | | | > > > > > > | > > > > | > > > | > > | > > | > > > > > > > > > | > > | > > > > > > > > > > > > < | > > | | > > > | > | > > > > > | > > > | | > > > > > > > > | > > > > > > > > | > > | | < < | | > > > > > > > | | | | > > > > | | | | | | | | | | > > > > | | | | | | | < | > > > > | > | | | > > > > | | | < | | | > < | | | > > | > | | | | | | | < < > > > > > > > > > > | | | | < | > < | > | < | | | > | > > > > > > > | > | | | | | | | < | < < < | < | < < | < | < | < | < | | | | | 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 | - (OFString *)stringByAppendingFormat: (OFConstantString *)format, ... { OFString *ret; va_list arguments; va_start(arguments, format); ret = [self stringByAppendingFormat: format arguments: arguments]; va_end(arguments); return ret; } - (OFString *)stringByAppendingFormat: (OFConstantString *)format arguments: (va_list)arguments { OFMutableString *new = [OFMutableString stringWithString: self]; [new appendFormat: format arguments: arguments]; [new makeImmutable]; return new; } - (OFString *)stringByPrependingString: (OFString *)string { OFMutableString *new = [[string mutableCopy] autorelease]; [new appendString: self]; [new makeImmutable]; return new; } - (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string withString: (OFString *)replacement { OFMutableString *new = [[self mutableCopy] autorelease]; [new replaceOccurrencesOfString: string withString: replacement]; [new makeImmutable]; return new; } - (OFString *)stringByReplacingOccurrencesOfString: (OFString *)string withString: (OFString *)replacement options: (int)options range: (OFRange)range { OFMutableString *new = [[self mutableCopy] autorelease]; [new replaceOccurrencesOfString: string withString: replacement options: options range: range]; [new makeImmutable]; return new; } - (OFString *)uppercaseString { OFMutableString *new = [[self mutableCopy] autorelease]; [new uppercase]; [new makeImmutable]; return new; } - (OFString *)lowercaseString { OFMutableString *new = [[self mutableCopy] autorelease]; [new lowercase]; [new makeImmutable]; return new; } - (OFString *)capitalizedString { OFMutableString *new = [[self mutableCopy] autorelease]; [new capitalize]; [new makeImmutable]; return new; } - (OFString *)stringByDeletingLeadingWhitespaces { OFMutableString *new = [[self mutableCopy] autorelease]; [new deleteLeadingWhitespaces]; [new makeImmutable]; return new; } - (OFString *)stringByDeletingTrailingWhitespaces { OFMutableString *new = [[self mutableCopy] autorelease]; [new deleteTrailingWhitespaces]; [new makeImmutable]; return new; } - (OFString *)stringByDeletingEnclosingWhitespaces { OFMutableString *new = [[self mutableCopy] autorelease]; [new deleteEnclosingWhitespaces]; [new makeImmutable]; return new; } - (bool)hasPrefix: (OFString *)prefix { OFUnichar *tmp; size_t prefixLength; bool hasPrefix; if ((prefixLength = prefix.length) > self.length) return false; tmp = OFAllocMemory(prefixLength, sizeof(OFUnichar)); @try { void *pool = objc_autoreleasePoolPush(); [self getCharacters: tmp inRange: OFRangeMake(0, prefixLength)]; hasPrefix = (memcmp(tmp, prefix.characters, prefixLength * sizeof(OFUnichar)) == 0); objc_autoreleasePoolPop(pool); } @finally { OFFreeMemory(tmp); } return hasPrefix; } - (bool)hasSuffix: (OFString *)suffix { OFUnichar *tmp; const OFUnichar *suffixCharacters; size_t length, suffixLength; bool hasSuffix; if ((suffixLength = suffix.length) > self.length) return false; length = self.length; tmp = OFAllocMemory(suffixLength, sizeof(OFUnichar)); @try { void *pool = objc_autoreleasePoolPush(); [self getCharacters: tmp inRange: OFRangeMake(length - suffixLength, suffixLength)]; suffixCharacters = suffix.characters; hasSuffix = (memcmp(tmp, suffixCharacters, suffixLength * sizeof(OFUnichar)) == 0); objc_autoreleasePoolPop(pool); } @finally { OFFreeMemory(tmp); } return hasSuffix; } - (OFArray *)componentsSeparatedByString: (OFString *)delimiter { return [self componentsSeparatedByString: delimiter options: 0]; } - (OFArray *)componentsSeparatedByString: (OFString *)delimiter options: (OFStringSeparationOptions)options { void *pool; OFMutableArray *array; const OFUnichar *characters, *delimiterCharacters; bool skipEmpty = (options & OFStringSkipEmptyComponents); size_t length = self.length; size_t delimiterLength = delimiter.length; size_t last; OFString *component; if (delimiter == nil) @throw [OFInvalidArgumentException exception]; if (delimiter.length == 0) return [OFArray arrayWithObject: self]; array = [OFMutableArray array]; pool = objc_autoreleasePoolPush(); characters = self.characters; delimiterCharacters = delimiter.characters; if (delimiterLength > length) { [array addObject: [[self copy] autorelease]]; [array makeImmutable]; objc_autoreleasePoolPop(pool); return array; } last = 0; for (size_t i = 0; i <= length - delimiterLength; i++) { if (memcmp(characters + i, delimiterCharacters, delimiterLength * sizeof(OFUnichar)) != 0) continue; component = [self substringWithRange: OFRangeMake(last, i - last)]; if (!skipEmpty || component.length > 0) [array addObject: component]; i += delimiterLength - 1; last = i + 1; } component = [self substringWithRange: OFRangeMake(last, length - last)]; if (!skipEmpty || component.length > 0) [array addObject: component]; [array makeImmutable]; objc_autoreleasePoolPop(pool); return array; } - (OFArray *) componentsSeparatedByCharactersInSet: (OFCharacterSet *)characterSet { return [self componentsSeparatedByCharactersInSet: characterSet options: 0]; } - (OFArray *) componentsSeparatedByCharactersInSet: (OFCharacterSet *)characterSet options: (OFStringSeparationOptions)options { OFMutableArray *array = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); bool skipEmpty = (options & OFStringSkipEmptyComponents); const OFUnichar *characters = self.characters; size_t length = self.length; bool (*characterIsMember)(id, SEL, OFUnichar) = (bool (*)(id, SEL, OFUnichar))[characterSet methodForSelector: @selector(characterIsMember:)]; size_t last; last = 0; for (size_t i = 0; i < length; i++) { if (characterIsMember(characterSet, @selector(characterIsMember:), characters[i])) { if (!skipEmpty || i != last) { OFString *component = [self substringWithRange: OFRangeMake(last, i - last)]; [array addObject: component]; } last = i + 1; } } if (!skipEmpty || length != last) { OFString *component = [self substringWithRange: OFRangeMake(last, length - last)]; [array addObject: component]; } [array makeImmutable]; objc_autoreleasePoolPop(pool); return array; } - (long long)longLongValue { return [self longLongValueWithBase: 10]; } - (long long)longLongValueWithBase: (int)base { void *pool = objc_autoreleasePoolPush(); const char *UTF8String = self.UTF8String; bool negative = false; long long value = 0; while (OFASCIIIsSpace(*UTF8String)) UTF8String++; switch (*UTF8String) { case '-': negative = true; case '+': UTF8String++; } if (UTF8String[0] == '0') { if (UTF8String[1] == 'x') { if (base == 0) base = 16; if (base != 16 || UTF8String[2] == '\0') @throw [OFInvalidFormatException exception]; UTF8String += 2; } else { if (base == 0) base = 8; UTF8String++; } } if (base == 0) base = 10; while (*UTF8String != '\0') { unsigned char c = OFASCIIToUpper(*UTF8String++); if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= ('A' - 10); else if (OFASCIIIsSpace(c)) { while (*UTF8String != '\0') if (!OFASCIIIsSpace(*UTF8String++)) @throw [OFInvalidFormatException exception]; break; } else @throw [OFInvalidFormatException exception]; if (c >= base) @throw [OFInvalidFormatException exception]; if (LLONG_MAX / base < value || LLONG_MAX - (value * base) < c) @throw [OFOutOfRangeException exception]; value = (value * base) + c; } if (negative) value *= -1; objc_autoreleasePoolPop(pool); return value; } - (unsigned long long)unsignedLongLongValue { return [self unsignedLongLongValueWithBase: 10]; } - (unsigned long long)unsignedLongLongValueWithBase: (int)base { void *pool = objc_autoreleasePoolPush(); const char *UTF8String = self.UTF8String; unsigned long long value = 0; while (OFASCIIIsSpace(*UTF8String)) UTF8String++; switch (*UTF8String) { case '-': @throw [OFInvalidFormatException exception]; case '+': UTF8String++; } if (UTF8String[0] == '0') { if (UTF8String[1] == 'x') { if (base == 0) base = 16; if (base != 16 || UTF8String[2] == '\0') @throw [OFInvalidFormatException exception]; UTF8String += 2; } else { if (base == 0) base = 8; UTF8String++; } } if (base == 0) base = 10; while (*UTF8String != '\0') { unsigned char c = OFASCIIToUpper(*UTF8String++); if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'Z') c -= ('A' - 10); else if (OFASCIIIsSpace(c)) { while (*UTF8String != '\0') if (!OFASCIIIsSpace(*UTF8String++)) @throw [OFInvalidFormatException exception]; break; } else @throw [OFInvalidFormatException exception]; if (c >= base) @throw [OFInvalidFormatException exception]; if (ULLONG_MAX / base < value || ULLONG_MAX - (value * base) < c) @throw [OFOutOfRangeException exception]; value = (value * base) + c; } objc_autoreleasePoolPop(pool); return value; } - (float)floatValue { void *pool = objc_autoreleasePoolPush(); OFString *stripped = self.stringByDeletingEnclosingWhitespaces; if ([stripped caseInsensitiveCompare: @"INF"] == OFOrderedSame || [stripped caseInsensitiveCompare: @"INFINITY"] == OFOrderedSame) return INFINITY; if ([stripped caseInsensitiveCompare: @"-INF"] == OFOrderedSame || [stripped caseInsensitiveCompare: @"-INFINITY"] == OFOrderedSame) return -INFINITY; if ([stripped caseInsensitiveCompare: @"NAN"] == OFOrderedSame) return NAN; if ([stripped caseInsensitiveCompare: @"-NAN"] == OFOrderedSame) return -NAN; #ifdef HAVE_STRTOF_L const char *UTF8String = self.UTF8String; #else /* * If we have no strtof_l, we have no other choice but to replace "." * with the locale's decimal point. */ OFString *decimalPoint = [OFLocale decimalPoint]; const char *UTF8String = [self stringByReplacingOccurrencesOfString: @"." withString: decimalPoint].UTF8String; #endif char *endPtr = NULL; float value; errno = 0; #ifdef HAVE_STRTOF_L value = strtof_l(UTF8String, &endPtr, cLocale); #else value = strtof(UTF8String, &endPtr); #endif if (value == HUGE_VALF && errno == ERANGE) @throw [OFOutOfRangeException exception]; /* Check if there are any invalid chars left */ if (endPtr != NULL) for (; *endPtr != '\0'; endPtr++) /* Use isspace since strtof uses the same. */ if (!isspace((unsigned char)*endPtr)) @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); return value; } - (double)doubleValue { void *pool = objc_autoreleasePoolPush(); OFString *stripped = self.stringByDeletingEnclosingWhitespaces; if ([stripped caseInsensitiveCompare: @"INF"] == OFOrderedSame || [stripped caseInsensitiveCompare: @"INFINITY"] == OFOrderedSame) return INFINITY; if ([stripped caseInsensitiveCompare: @"-INF"] == OFOrderedSame || [stripped caseInsensitiveCompare: @"-INFINITY"] == OFOrderedSame) return -INFINITY; if ([stripped caseInsensitiveCompare: @"NAN"] == OFOrderedSame) return NAN; if ([stripped caseInsensitiveCompare: @"-NAN"] == OFOrderedSame) return -NAN; #ifdef HAVE_STRTOD_L const char *UTF8String = self.UTF8String; #else /* * If we have no strtod_l, we have no other choice but to replace "." * with the locale's decimal point. */ OFString *decimalPoint = [OFLocale decimalPoint]; const char *UTF8String = [self stringByReplacingOccurrencesOfString: @"." withString: decimalPoint].UTF8String; #endif char *endPtr = NULL; double value; errno = 0; #ifdef HAVE_STRTOD_L value = strtod_l(UTF8String, &endPtr, cLocale); #else value = strtod(UTF8String, &endPtr); #endif if (value == HUGE_VAL && errno == ERANGE) @throw [OFOutOfRangeException exception]; /* Check if there are any invalid chars left */ if (endPtr != NULL) for (; *endPtr != '\0'; endPtr++) /* Use isspace since strtod uses the same. */ if (!isspace((unsigned char)*endPtr)) @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); return value; } - (const OFUnichar *)characters { size_t length = self.length; OFUnichar *buffer; const OFUnichar *ret; buffer = OFAllocMemory(length, sizeof(OFUnichar)); @try { [self getCharacters: buffer inRange: OFRangeMake(0, length)]; ret = [[OFData dataWithItemsNoCopy: buffer count: length itemSize: sizeof(OFUnichar) freeWhenDone: true] items]; } @catch (id e) { OFFreeMemory(buffer); @throw e; } return ret; } - (const OFChar16 *)UTF16String { return [self UTF16StringWithByteOrder: OFByteOrderNative]; } - (const OFChar16 *)UTF16StringWithByteOrder: (OFByteOrder)byteOrder { void *pool = objc_autoreleasePoolPush(); const OFUnichar *characters = self.characters; size_t length = self.length; OFChar16 *buffer; size_t j; bool swap = (byteOrder != OFByteOrderNative); const OFChar16 *ret; /* Allocate memory for the worst case */ buffer = OFAllocMemory((length + 1) * 2, sizeof(OFChar16)); j = 0; for (size_t i = 0; i < length; i++) { OFUnichar c = characters[i]; if (c > 0x10FFFF) { OFFreeMemory(buffer); @throw [OFInvalidEncodingException exception]; } if (swap) { if (c > 0xFFFF) { c -= 0x10000; buffer[j++] = OFByteSwap16(0xD800 | (c >> 10)); buffer[j++] = OFByteSwap16(0xDC00 | (c & 0x3FF)); } else buffer[j++] = OFByteSwap16(c); } else { if (c > 0xFFFF) { c -= 0x10000; buffer[j++] = 0xD800 | (c >> 10); buffer[j++] = 0xDC00 | (c & 0x3FF); } else buffer[j++] = c; } } buffer[j] = 0; @try { buffer = OFResizeMemory(buffer, j + 1, sizeof(OFChar16)); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } objc_autoreleasePoolPop(pool); @try { ret = [[OFData dataWithItemsNoCopy: buffer count: j + 1 itemSize: sizeof(OFChar16) freeWhenDone: true] items]; } @catch (id e) { OFFreeMemory(buffer); @throw e; } return ret; } - (size_t)UTF16StringLength { const OFUnichar *characters = self.characters; size_t length, UTF16StringLength; length = UTF16StringLength = self.length; for (size_t i = 0; i < length; i++) if (characters[i] > 0xFFFF) UTF16StringLength++; return UTF16StringLength; } - (const OFChar32 *)UTF32String { return [self UTF32StringWithByteOrder: OFByteOrderNative]; } - (const OFChar32 *)UTF32StringWithByteOrder: (OFByteOrder)byteOrder { size_t length = self.length; OFChar32 *buffer; const OFChar32 *ret; buffer = OFAllocMemory(length + 1, sizeof(OFChar32)); @try { [self getCharacters: buffer inRange: OFRangeMake(0, length)]; buffer[length] = 0; if (byteOrder != OFByteOrderNative) for (size_t i = 0; i < length; i++) buffer[i] = OFByteSwap32(buffer[i]); ret = [[OFData dataWithItemsNoCopy: buffer count: length + 1 itemSize: sizeof(OFChar32) freeWhenDone: true] items]; } @catch (id e) { OFFreeMemory(buffer); @throw e; } return ret; } - (OFData *)dataWithEncoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); OFData *data = [OFData dataWithItems: [self cStringWithEncoding: encoding] count: [self cStringLengthWithEncoding: encoding]]; [data retain]; objc_autoreleasePoolPop(pool); return [data autorelease]; } #ifdef OF_HAVE_UNICODE_TABLES - (OFString *)decomposedStringWithCanonicalMapping { return decomposedString(self, OFUnicodeDecompositionTable, OFUnicodeDecompositionTableSize); } - (OFString *)decomposedStringWithCompatibilityMapping { return decomposedString(self, OFUnicodeDecompositionCompatTable, OFUnicodeDecompositionCompatTableSize); } #endif #ifdef OF_WINDOWS - (OFString *)stringByExpandingWindowsEnvironmentStrings { if ([OFSystemInfo isWindowsNT]) { wchar_t buffer[512]; size_t length; if ((length = ExpandEnvironmentStringsW(self.UTF16String, buffer, sizeof(buffer))) == 0) return self; return [OFString stringWithUTF16String: buffer length: length - 1]; } else { OFStringEncoding encoding = [OFLocale encoding]; char buffer[512]; size_t length; if ((length = ExpandEnvironmentStringsA( [self cStringWithEncoding: encoding], buffer, sizeof(buffer))) == 0) return self; return [OFString stringWithCString: buffer encoding: encoding length: length - 1]; } } #endif #ifdef OF_HAVE_FILES - (void)writeToFile: (OFString *)path { [self writeToFile: path encoding: OFStringEncodingUTF8]; } - (void)writeToFile: (OFString *)path encoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); OFFile *file = [OFFile fileWithPath: path mode: @"w"]; [file writeString: self encoding: encoding]; objc_autoreleasePoolPop(pool); } #endif - (void)writeToURL: (OFURL *)URL { [self writeToURL: URL encoding: OFStringEncodingUTF8]; } - (void)writeToURL: (OFURL *)URL encoding: (OFStringEncoding)encoding { void *pool = objc_autoreleasePoolPush(); OFURLHandler *URLHandler; OFStream *stream; if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil) @throw [OFUnsupportedProtocolException exceptionWithURL: URL]; stream = [URLHandler openItemAtURL: URL mode: @"w"]; [stream writeString: self encoding: encoding]; objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (void)enumerateLinesUsingBlock: (OFStringLineEnumerationBlock)block { void *pool = objc_autoreleasePoolPush(); const OFUnichar *characters = self.characters; size_t i, last = 0, length = self.length; bool stop = false, lastCarriageReturn = false; for (i = 0; i < length && !stop; i++) { if (lastCarriageReturn && characters[i] == '\n') { lastCarriageReturn = false; last++; continue; } if (characters[i] == '\n' || characters[i] == '\r') { void *pool2 = objc_autoreleasePoolPush(); block([self substringWithRange: OFRangeMake(last, i - last)], &stop); last = i + 1; objc_autoreleasePoolPop(pool2); } lastCarriageReturn = (characters[i] == '\r'); } if (!stop) block([self substringWithRange: OFRangeMake(last, i - last)], &stop); objc_autoreleasePoolPop(pool); } #endif @end |
Modified src/OFSubarray.h from [cb560d9395] to [06376fcb2e].
1 | /* | < < | | | < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFArray.h" OF_ASSUME_NONNULL_BEGIN @interface OFSubarray: OFArray { OFArray *_array; OFRange _range; } + (instancetype)arrayWithArray: (OFArray *)array range: (OFRange)range; - (instancetype)initWithArray: (OFArray *)array range: (OFRange)range; @end OF_ASSUME_NONNULL_END |
Modified src/OFSubarray.m from [32cdeea2aa] to [0aad1eac45].
1 | /* | < < | | < | < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFSubarray.h" #import "OFOutOfRangeException.h" @implementation OFSubarray + (instancetype)arrayWithArray: (OFArray *)array range: (OFRange)range { return [[[self alloc] initWithArray: array range: range] autorelease]; } - (instancetype)initWithArray: (OFArray *)array range: (OFRange)range { self = [super init]; @try { /* Should usually be retain, as it's useless with a copy */ _array = [array copy]; _range = range; |
︙ | ︙ | |||
62 63 64 65 66 67 68 | { if (idx >= _range.length) @throw [OFOutOfRangeException exception]; return [_array objectAtIndex: idx + _range.location]; } | | < | < | | | | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | { if (idx >= _range.length) @throw [OFOutOfRangeException exception]; return [_array objectAtIndex: idx + _range.location]; } - (void)getObjects: (id *)buffer inRange: (OFRange)range { if (range.length > SIZE_MAX - range.location || range.location + range.length > _range.length) @throw [OFOutOfRangeException exception]; range.location += _range.location; [_array getObjects: buffer inRange: range]; } - (size_t)indexOfObject: (id)object { size_t idx = [_array indexOfObject: object]; if (idx < _range.location) return OFNotFound; idx -= _range.location; if (idx >= _range.length) return OFNotFound; return idx; } - (size_t)indexOfObjectIdenticalTo: (id)object { size_t idx = [_array indexOfObjectIdenticalTo: object]; if (idx < _range.location) return OFNotFound; idx -= _range.location; if (idx >= _range.length) return OFNotFound; return idx; } - (OFArray *)objectsInRange: (OFRange)range { if (range.length > SIZE_MAX - range.location || range.location + range.length > _range.length) @throw [OFOutOfRangeException exception]; range.location += _range.location; return [_array objectsInRange: range]; } @end |
Renamed and modified src/OFProcess.h [9ba5254960] to src/OFSubprocess.h [edb6555d8e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
38 39 40 41 42 43 44 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFDictionary OF_GENERIC(KeyType, ObjectType); /** | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFDictionary OF_GENERIC(KeyType, ObjectType); /** * @class OFSubprocess OFSubprocess.h ObjFW/OFSubprocess.h * * @brief A class for stream-like communication with a newly created subprocess. */ OF_SUBCLASSING_RESTRICTED @interface OFSubprocess: OFStream #ifndef OF_WINDOWS <OFReadyForReadingObserving, OFReadyForWritingObserving> #endif { #ifndef OF_WINDOWS pid_t _pid; int _readPipe[2], _writePipe[2]; #else HANDLE _handle, _readPipe[2], _writePipe[2]; #endif int _status; bool _atEndOfStream; } /** * @brief Creates a new OFSubprocess with the specified program and invokes the * program. * * @param program The program to execute. If it does not start with a slash, the * search path specified in PATH is used. * @return A new, autoreleased OFSubprocess. */ + (instancetype)subprocessWithProgram: (OFString *)program; /** * @brief Creates a new OFSubprocess with the specified program and arguments * and invokes the program. * * @param program The program to execute. If it does not start with a slash, the * search path specified in PATH is used. * @param arguments The arguments to pass to the program, or `nil` * @return A new, autoreleased OFSubprocess. */ + (instancetype) subprocessWithProgram: (OFString *)program arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments; /** * @brief Creates a new OFSubprocess with the specified program, program name * and arguments and invokes the program. * * @param program The program to execute. If it does not start with a slash, the * search path specified in PATH is used. * @param programName The program name for the program to invoke (argv[0]). * Usually, this is equal to program. * @param arguments The arguments to pass to the program, or `nil` * @return A new, autoreleased OFSubprocess. */ + (instancetype) subprocessWithProgram: (OFString *)program programName: (OFString *)programName arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments; /** * @brief Creates a new OFSubprocess with the specified program, program name, * arguments and environment and invokes the program. * * @param program The program to execute. If it does not start with a slash, the * search path specified in PATH is used. * @param programName The program name for the program to invoke (argv[0]). * Usually, this is equal to program. * @param arguments The arguments to pass to the program, or `nil` * @param environment The environment to pass to the program, or `nil`. If it * is not `nil`, the passed dictionary will be used to * override the environment. If you want to add to the * existing environment, you need to get the existing * environment first, copy it, modify it and then pass it. * @return A new, autoreleased OFSubprocess. */ + (instancetype) subprocessWithProgram: (OFString *)program programName: (OFString *)programName arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments environment: (nullable OFDictionary OF_GENERIC(OFString *, OFString *) *)environment; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFSubprocess with the specified * program and invokes the program. * * @param program The program to execute. If it does not start with a slash, the * search path specified in PATH is used. * @return An initialized OFSubprocess. */ - (instancetype)initWithProgram: (OFString *)program; /** * @brief Initializes an already allocated OFSubprocess with the specified * program and arguments and invokes the program. * * @param program The program to execute. If it does not start with a slash, the * search path specified in PATH is used. * @param arguments The arguments to pass to the program, or `nil` * @return An initialized OFSubprocess. */ - (instancetype) initWithProgram: (OFString *)program arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments; /** * @brief Initializes an already allocated OFSubprocess with the specified * program, program name and arguments and invokes the program. * * @param program The program to execute. If it does not start with a slash, the * search path specified in PATH is used. * @param programName The program name for the program to invoke (argv[0]). * Usually, this is equal to program. * @param arguments The arguments to pass to the program, or `nil` * @return An initialized OFSubprocess. */ - (instancetype) initWithProgram: (OFString *)program programName: (OFString *)programName arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments; /** * @brief Initializes an already allocated OFSubprocess with the specified * program, program name, arguments and environment and invokes the * program. * * @param program The program to execute. If it does not start with a slash, the * search path specified in PATH is used. * @param programName The program name for the program to invoke (argv[0]). * Usually, this is equal to program. * @param arguments The arguments to pass to the program, or `nil` * @param environment The environment to pass to the program, or `nil`. If it * is not `nil`, the passed dictionary will be used to * override the environment. If you want to add to the * existing environment, you need to get the existing * environment first, copy it, modify it and then pass it. * @return An initialized OFSubprocess. */ - (instancetype) initWithProgram: (OFString *)program programName: (OFString *)programName arguments: (nullable OFArray OF_GENERIC(OFString *) *)arguments environment: (nullable OFDictionary OF_GENERIC(OFString *, OFString *) *)environment OF_DESIGNATED_INITIALIZER; /** * @brief Closes the write direction of the subprocess. * * This method needs to be called for some programs before data can be read, * since some programs don't start processing before the write direction is * closed. */ - (void)closeForWriting; /** * @brief Waits for the subprocess to terminate and returns the exit status. * * If the subprocess has already exited, this returns the exit status * immediately. */ - (int)waitForTermination; @end OF_ASSUME_NONNULL_END |
Renamed and modified src/OFProcess.m [07d8cb1dd6] to src/OFSubprocess.m [c37900d1dc].
1 | /* | < < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #ifdef OF_WINDOWS # include "platform/Windows/OFSubprocess.m" #else # include "platform/POSIX/OFSubprocess.m" #endif |
Modified src/OFSystemInfo.h from [61055b02a1] to [c96bc638d9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | */ OF_SUBCLASSING_RESTRICTED @interface OFSystemInfo: OFObject #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) size_t pageSize; @property (class, readonly, nonatomic) size_t numberOfCPUs; @property (class, readonly, nonatomic) OFString *ObjFWVersion; | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | */ OF_SUBCLASSING_RESTRICTED @interface OFSystemInfo: OFObject #ifdef OF_HAVE_CLASS_PROPERTIES @property (class, readonly, nonatomic) size_t pageSize; @property (class, readonly, nonatomic) size_t numberOfCPUs; @property (class, readonly, nonatomic) OFString *ObjFWVersion; @property (class, readonly, nonatomic) unsigned short ObjFWVersionMajor; @property (class, readonly, nonatomic) unsigned short ObjFWVersionMinor; @property (class, readonly, nullable, nonatomic) OFString *operatingSystemName; @property (class, readonly, nullable, nonatomic) OFString *operatingSystemVersion; # ifdef OF_HAVE_FILES @property (class, readonly, nullable, nonatomic) OFString *userDataPath; @property (class, readonly, nullable, nonatomic) OFString *userConfigPath; # endif |
︙ | ︙ | |||
87 88 89 90 91 92 93 | + (OFString *)ObjFWVersion; /** * @brief The major version of ObjFW. * * @return The major version of ObjFW */ | | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | + (OFString *)ObjFWVersion; /** * @brief The major version of ObjFW. * * @return The major version of ObjFW */ + (unsigned short)ObjFWVersionMajor; /** * @brief The minor version of ObjFW. * * @return The minor version of ObjFW */ + (unsigned short)ObjFWVersionMinor; /** * @brief Returns the name of the operating system the application is running * on. * * @return The name of the operating system the application is running on */ |
︙ | ︙ | |||
116 117 118 119 120 121 122 | */ + (nullable OFString *)operatingSystemVersion; #ifdef OF_HAVE_FILES /** * @brief Returns the path where user data for the application can be stored. * | | | | > | | > > > > > > > > > > > > > > > > > > > | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | */ + (nullable OFString *)operatingSystemVersion; #ifdef OF_HAVE_FILES /** * @brief Returns the path where user data for the application can be stored. * * On UNIX systems, this adheres to the XDG Base Directory specification.@n * On macOS and iOS, it uses the `NSApplicationSupportDirectory` directory.@n * On Windows, it uses the `APPDATA` environment variable.@n * On Haiku, it uses the `B_USER_SETTINGS_DIRECTORY` directory.@n * On AmigaOS and MorphOS, it returns `PROGDIR:`. * * @return The path where user data for the application can be stored */ + (nullable OFString *)userDataPath; /** * @brief Returns the path where user configuration for the application can be * stored. * * On UNIX systems, this adheres to the XDG Base Directory specification.@n * On macOS and iOS, it uses the `Preferences` directory inside of * `NSLibraryDirectory` directory.@n * On Windows, it uses the `APPDATA` environment variable.@n * On Haiku, it uses the `B_USER_SETTINGS_DIRECTORY` directory. * On AmigaOS and MorphOS, it returns `PROGDIR:`. * * @return The path where user configuration for the application can be stored */ + (nullable OFString *)userConfigPath; /** * @brief Returns a path where temporary files for can be stored. * * If possible, returns a temporary directory for the user, otherwise returns a * global temporary directory. * * On UNIX systems, this adheres to the XDG Base Directory specification and * returns `/tmp` if `XDG_RUNTIME_DIR` is not set.@n * On macOS and iOS, this uses `_CS_DARWIN_USER_TEMP_DIR`, falling back to * `/tmp` if this fails.@n * On Windows, it uses `GetTempPath`.@n * On Haiku, it uses the `B_SYSTEM_TEMP_DIRECTORY` directory. * On AmigaOS and MorphOS, it returns `T:`. * * @return A path where temporary files can be stored */ + (nullable OFString *)temporaryDirectoryPath; #endif /** * @brief Returns the vendor of the CPU. * * If the vendor could not be determined, `nil` is returned instead. * |
︙ | ︙ |
Modified src/OFSystemInfo.m from [97e07274dd] to [2ea5196f61].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | #include "unistd_wrapper.h" #include "platform.h" #ifdef HAVE_SYS_UTSNAME_H # include <sys/utsname.h> #endif | | > > > > > < < > < < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #include "unistd_wrapper.h" #include "platform.h" #ifdef HAVE_SYS_UTSNAME_H # include <sys/utsname.h> #endif #if defined(OF_MACOS) || defined(OF_IOS) || defined(OF_NETBSD) # include <sys/sysctl.h> #endif #ifdef OF_AMIGAOS # include <exec/execbase.h> # include <proto/exec.h> #endif #if defined(OF_AMIGAOS4) # include <exec/exectags.h> #elif defined(OF_MORPHOS) # include <exec/system.h> #endif #import "OFSystemInfo.h" #import "OFApplication.h" #import "OFArray.h" #import "OFDictionary.h" #import "OFLocale.h" #import "OFOnce.h" #import "OFString.h" #import "OFNotImplementedException.h" #if defined(OF_MACOS) || defined(OF_IOS) # ifdef HAVE_SYSDIR_H # include <sysdir.h> # endif #endif #ifdef OF_WINDOWS # include <windows.h> |
︙ | ︙ | |||
89 90 91 92 93 94 95 | extern NSSearchPathEnumerationState NSStartSearchPathEnumeration( NSSearchPathDirectory, NSSearchPathDomainMask); extern NSSearchPathEnumerationState NSGetNextSearchPathEnumeration( NSSearchPathEnumerationState, char *); #endif #if defined(OF_X86_64) || defined(OF_X86) | | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | extern NSSearchPathEnumerationState NSStartSearchPathEnumeration( NSSearchPathDirectory, NSSearchPathDomainMask); extern NSSearchPathEnumerationState NSGetNextSearchPathEnumeration( NSSearchPathEnumerationState, char *); #endif #if defined(OF_X86_64) || defined(OF_X86) struct X86Regs { uint32_t eax, ebx, ecx, edx; }; #endif static size_t pageSize = 4096; static size_t numberOfCPUs = 1; static OFString *operatingSystemName = nil; |
︙ | ︙ | |||
162 163 164 165 166 167 168 | } # endif #elif defined(OF_WINDOWS) # ifdef OF_HAVE_FILES void *pool = objc_autoreleasePoolPush(); @try { | | | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | } # endif #elif defined(OF_WINDOWS) # ifdef OF_HAVE_FILES void *pool = objc_autoreleasePoolPush(); @try { OFStringEncoding encoding = [OFLocale encoding]; char systemDir[PATH_MAX]; UINT systemDirLen; OFString *systemDirString; const char *path; void *buffer; DWORD bufferLen; |
︙ | ︙ | |||
213 214 215 216 217 218 219 | } } @finally { objc_autoreleasePoolPop(pool); } # endif #elif defined(OF_ANDROID) /* TODO */ | | | | | < < | | | | | | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | } } @finally { objc_autoreleasePoolPop(pool); } # endif #elif defined(OF_ANDROID) /* TODO */ #elif defined(OF_AMIGAOS) operatingSystemVersion = [[OFString alloc] initWithFormat: @"Kickstart %u.%u", SysBase->LibNode.lib_Version, SysBase->SoftVer]; #elif defined(OF_WII) || defined(NINTENDO_3DS) || defined(OF_NINTENDO_DS) || \ defined(OF_PSP) || defined(OF_MSDOS) /* Intentionally nothing */ #elif defined(HAVE_SYS_UTSNAME_H) && defined(HAVE_UNAME) struct utsname utsname; if (uname(&utsname) != 0) return; operatingSystemVersion = [[OFString alloc] initWithCString: utsname.release encoding: [OFLocale encoding]]; #endif } #if defined(OF_X86_64) || defined(OF_X86) static OF_INLINE struct X86Regs OF_CONST_FUNC x86CPUID(uint32_t eax, uint32_t ecx) { struct X86Regs regs; # if defined(OF_X86_64) && defined(__GNUC__) __asm__ ( "cpuid" : "=a"(regs.eax), "=b"(regs.ebx), "=c"(regs.ecx), "=d"(regs.edx) : "a"(eax), "c"(ecx) ); # elif defined(OF_X86) && defined(__GNUC__) /* * This workaround is required by older GCC versions when using -fPIC, * as ebx is a special register in PIC code. Yes, GCC is indeed not * able to just push a register onto the stack before the __asm__ block * and to pop it afterwards. */ __asm__ ( |
︙ | ︙ | |||
319 320 321 322 323 324 325 | } + (OFString *)ObjFWVersion { return @PACKAGE_VERSION; } | | | | | | | | < | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | } + (OFString *)ObjFWVersion { return @PACKAGE_VERSION; } + (unsigned short)ObjFWVersionMajor { return OBJFW_VERSION_MAJOR; } + (unsigned short)ObjFWVersionMinor { return OBJFW_VERSION_MINOR; } + (OFString *)operatingSystemName { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, initOperatingSystemName); return operatingSystemName; } + (OFString *)operatingSystemVersion { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, initOperatingSystemVersion); return operatingSystemVersion; } #ifdef OF_HAVE_FILES + (OFString *)userDataPath { # if defined(OF_MACOS) || defined(OF_IOS) char pathC[PATH_MAX]; OFMutableString *path; # ifdef HAVE_SYSDIR_START_SEARCH_PATH_ENUMERATION if (@available(macOS 10.12, iOS 10, *)) { sysdir_search_path_enumeration_state state; state = sysdir_start_search_path_enumeration( SYSDIR_DIRECTORY_APPLICATION_SUPPORT, SYSDIR_DOMAIN_MASK_USER); if (sysdir_get_next_search_path_enumeration(state, pathC) == 0) @throw [OFNotImplementedException |
︙ | ︙ | |||
388 389 390 391 392 393 394 | OFString *home; if ((home = [env objectForKey: @"HOME"]) == nil) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; | | | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | OFString *home; if ((home = [env objectForKey: @"HOME"]) == nil) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; [path deleteCharactersInRange: OFRangeMake(0, 1)]; [path prependString: home]; } [path makeImmutable]; return path; # elif defined(OF_WINDOWS) |
︙ | ︙ | |||
446 447 448 449 450 451 452 | + (OFString *)userConfigPath { # if defined(OF_MACOS) || defined(OF_IOS) char pathC[PATH_MAX]; OFMutableString *path; # ifdef HAVE_SYSDIR_START_SEARCH_PATH_ENUMERATION | | < | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | + (OFString *)userConfigPath { # if defined(OF_MACOS) || defined(OF_IOS) char pathC[PATH_MAX]; OFMutableString *path; # ifdef HAVE_SYSDIR_START_SEARCH_PATH_ENUMERATION if (@available(macOS 10.12, iOS 10, *)) { sysdir_search_path_enumeration_state state; state = sysdir_start_search_path_enumeration( SYSDIR_DIRECTORY_LIBRARY, SYSDIR_DOMAIN_MASK_USER); if (sysdir_get_next_search_path_enumeration(state, pathC) == 0) @throw [OFNotImplementedException exceptionWithSelector: _cmd |
︙ | ︙ | |||
480 481 482 483 484 485 486 | OFString *home; if ((home = [env objectForKey: @"HOME"]) == nil) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; | | < | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | OFString *home; if ((home = [env objectForKey: @"HOME"]) == nil) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; [path deleteCharactersInRange: OFRangeMake(0, 1)]; [path prependString: home]; } [path appendString: @"/Preferences"]; [path makeImmutable]; return path; # elif defined(OF_WINDOWS) OFDictionary *env = [OFApplication environment]; OFString *appData; |
︙ | ︙ | |||
524 525 526 527 528 529 530 531 532 533 534 | if ((var = [env objectForKey: @"HOME"]) == nil) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; return [var stringByAppendingPathComponent: @".config"]; # endif } #endif + (OFString *)CPUVendor { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | > > | > > > > < | | > > > > > > > > > > > | > > > > > > > > > > > > > | | | | | | | | | | | | 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 | if ((var = [env objectForKey: @"HOME"]) == nil) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; return [var stringByAppendingPathComponent: @".config"]; # endif } + (OFString *)temporaryDirectoryPath { # if defined(OF_MACOS) || defined(OF_IOS) char buffer[PATH_MAX]; size_t length; if ((length = confstr(_CS_DARWIN_USER_TEMP_DIR, buffer, PATH_MAX)) == 0) return @"/tmp"; return [OFString stringWithCString: buffer encoding: [OFLocale encoding] length: length - 1]; # elif defined(OF_WINDOWS) if ([self isWindowsNT]) { wchar_t buffer[PATH_MAX]; if (!GetTempPathW(PATH_MAX, buffer)) return nil; return [OFString stringWithUTF16String: buffer]; } else { char buffer[PATH_MAX]; if (!GetTempPathA(PATH_MAX, buffer)) return nil; return [OFString stringWithCString: buffer encoding: [OFLocale encoding]]; } # elif defined(OF_HAIKU) char pathC[PATH_MAX]; if (find_directory(B_SYSTEM_TEMP_DIRECTORY, 0, false, pathC, PATH_MAX) != B_OK) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; return [OFString stringWithUTF8String: pathC]; # elif defined(OF_AMIGAOS) return @"T:"; # elif defined(OF_MSDOS) return [[OFApplication environment] objectForKey: @"TEMP"]; # elif defined(OF_MINT) return @"u:\\tmp"; # else OFString *path = [[OFApplication environment] objectForKey: @"XDG_RUNTIME_DIR"]; if (path != nil) return path; return @"/tmp"; # endif } #endif + (OFString *)CPUVendor { #if (defined(OF_X86_64) || defined(OF_X86)) && defined(__GNUC__) struct X86Regs regs = x86CPUID(0, 0); uint32_t buffer[3]; if (regs.eax == 0) return nil; buffer[0] = regs.ebx; buffer[1] = regs.edx; buffer[2] = regs.ecx; return [OFString stringWithCString: (char *)buffer encoding: OFStringEncodingASCII length: 12]; #elif defined(OF_M68K) return @"Motorola"; #else return nil; #endif } + (OFString *)CPUModel { #if (defined(OF_X86_64) || defined(OF_X86)) && defined(__GNUC__) struct X86Regs regs = x86CPUID(0x80000000, 0); uint32_t buffer[12]; size_t i; if (regs.eax < 0x80000004) return nil; i = 0; for (uint32_t eax = 0x80000002; eax <= 0x80000004; eax++) { regs = x86CPUID(eax, 0); buffer[i++] = regs.eax; buffer[i++] = regs.ebx; buffer[i++] = regs.ecx; buffer[i++] = regs.edx; } return [OFString stringWithCString: (char *)buffer encoding: OFStringEncodingASCII]; #elif defined(OF_MACOS) || defined(OF_IOS) char buffer[128]; size_t length = sizeof(buffer); if (sysctlbyname("machdep.cpu.brand_string", &buffer, &length, NULL, 0) != 0) return nil; return [OFString stringWithCString: buffer encoding: [OFLocale encoding] length: length]; #elif defined(OF_AMIGAOS4) CONST_STRPTR model, version; GetCPUInfoTags(GCIT_ModelString, &model, GCIT_VersionString, &version, TAG_END); if (version != NULL) return [OFString stringWithFormat: @"%s V%s", model, version]; else return [OFString stringWithCString: model encoding: OFStringEncodingASCII]; #elif defined(OF_AMIGAOS_M68K) if (SysBase->AttnFlags & AFF_68060) return @"68060"; if (SysBase->AttnFlags & AFF_68040) return @"68040"; if (SysBase->AttnFlags & AFF_68030) return @"68030"; if (SysBase->AttnFlags & AFF_68020) return @"68020"; if (SysBase->AttnFlags & AFF_68010) return @"68010"; else return @"68000"; #else return nil; #endif } #if defined(OF_X86_64) || defined(OF_X86) + (bool)supportsMMX { return (x86CPUID(1, 0).edx & (1u << 23)); } + (bool)supportsSSE { return (x86CPUID(1, 0).edx & (1u << 25)); } + (bool)supportsSSE2 { return (x86CPUID(1, 0).edx & (1u << 26)); } + (bool)supportsSSE3 { return (x86CPUID(1, 0).ecx & (1u << 0)); } + (bool)supportsSSSE3 { return (x86CPUID(1, 0).ecx & (1u << 9)); } + (bool)supportsSSE41 { return (x86CPUID(1, 0).ecx & (1u << 19)); } + (bool)supportsSSE42 { return (x86CPUID(1, 0).ecx & (1u << 20)); } + (bool)supportsAVX { return (x86CPUID(1, 0).ecx & (1u << 28)); } + (bool)supportsAVX2 { return x86CPUID(0, 0).eax >= 7 && (x86CPUID(7, 0).ebx & (1u << 5)); } + (bool)supportsAESNI { return (x86CPUID(1, 0).ecx & (1u << 25)); } + (bool)supportsSHAExtensions { return (x86CPUID(7, 0).ebx & (1u << 29)); } #endif #if defined(OF_POWERPC) || defined(OF_POWERPC64) + (bool)supportsAltiVec { # if defined(OF_MACOS) |
︙ | ︙ |
Modified src/OFTCPSocket.h from [63c13750a5] to [fc53b099cc].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | #ifdef OF_HAVE_BLOCKS /** * @brief A block which is called when the socket connected. * * @param exception An exception which occurred while connecting the socket or * `nil` on success */ | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #ifdef OF_HAVE_BLOCKS /** * @brief A block which is called when the socket connected. * * @param exception An exception which occurred while connecting the socket or * `nil` on success */ typedef void (^OFTCPSocketAsyncConnectBlock)(id _Nullable exception); #endif /** * @protocol OFTCPSocketDelegate OFTCPSocket.h ObjFW/OFTCPSocket.h * * A delegate for OFTCPSocket. */ |
︙ | ︙ | |||
144 145 146 147 148 149 150 | * @brief Returns the port to use as a SOCKS5 proxy when creating a new socket * * @return The port to use as a SOCKS5 proxy when creating a new socket */ + (uint16_t)SOCKS5Port; /** | | | < | | < | | | | | | | | | < < < < < < < < < | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | * @brief Returns the port to use as a SOCKS5 proxy when creating a new socket * * @return The port to use as a SOCKS5 proxy when creating a new socket */ + (uint16_t)SOCKS5Port; /** * @brief Connects the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to */ - (void)connectToHost: (OFString *)host port: (uint16_t)port; /** * @brief Asynchronously connects the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to */ - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port; /** * @brief Asynchronously connects the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to * @param runLoopMode The run loop mode in which to perform the async connect */ - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode; #ifdef OF_HAVE_BLOCKS /** * @brief Asynchronously connects the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to * @param block The block to execute once the connection has been established */ - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port block: (OFTCPSocketAsyncConnectBlock)block; /** * @brief Asynchronously connects the OFTCPSocket to the specified destination. * * @param host The host to connect to * @param port The port on the host to connect to * @param runLoopMode The run loop mode in which to perform the async connect * @param block The block to execute once the connection has been established */ - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode block: (OFTCPSocketAsyncConnectBlock)block; #endif /** * @brief Binds the socket to the specified host and port. * * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for * IPv6 to bind to all. * @param port The port to bind to. If the port is 0, an unused port will be * chosen, which can be obtained using the return value. * @return The port the socket was bound to */ - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port; @end OF_ASSUME_NONNULL_END |
Modified src/OFTCPSocket.m from [dc32b6d4c9] to [06bb1cad5c].
1 | /* | < < | > > > > > | < > > < < | | < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #ifndef _XOPEN_SOURCE_EXTENDED # define _XOPEN_SOURCE_EXTENDED #endif #define __NO_EXT_QNX #define _HPUX_ALT_XOPEN_SOCKET_API #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFTCPSocket.h" #import "OFDNSResolver.h" #import "OFData.h" #import "OFDate.h" #import "OFIPSocketAsyncConnector.h" #import "OFRunLoop.h" #import "OFRunLoop+Private.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFString.h" #import "OFTCPSocketSOCKS5Connector.h" #import "OFThread.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" #import "OFGetOptionFailedException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFSetOptionFailedException.h" static const OFRunLoopMode connectRunLoopMode = @"OFTCPSocketConnectRunLoopMode"; static OFString *defaultSOCKS5Host = nil; static uint16_t defaultSOCKS5Port = 1080; @interface OFTCPSocket () <OFIPSocketAsyncConnecting> @end |
︙ | ︙ | |||
130 131 132 133 134 135 136 | - (void)dealloc { [_SOCKS5Host release]; [super dealloc]; } | | | | | | | | | | < | | < | | > < < | < | | | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | - (void)dealloc { [_SOCKS5Host release]; [super dealloc]; } - (bool)of_createSocketForAddress: (const OFSocketAddress *)address errNo: (int *)errNo { #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if ((_socket = socket(address->sockaddr.sockaddr.sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)) == OFInvalidSocketHandle) { *errNo = OFSocketErrNo(); return false; } #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif return true; } - (bool)of_connectSocketToAddress: (const OFSocketAddress *)address errNo: (int *)errNo { if (_socket == OFInvalidSocketHandle) @throw [OFNotOpenException exceptionWithObject: self]; /* Cast needed for AmigaOS, where the argument is declared non-const */ if (connect(_socket, (struct sockaddr *)&address->sockaddr.sockaddr, address->length) != 0) { *errNo = OFSocketErrNo(); return false; } return true; } - (void)of_closeSocket { closesocket(_socket); _socket = OFInvalidSocketHandle; } - (void)connectToHost: (OFString *)host port: (uint16_t)port { void *pool = objc_autoreleasePoolPush(); id <OFTCPSocketDelegate> delegate = _delegate; OFTCPSocketConnectDelegate *connectDelegate = [[[OFTCPSocketConnectDelegate alloc] init] autorelease]; OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; _delegate = connectDelegate; [self asyncConnectToHost: host port: port runLoopMode: connectRunLoopMode]; while (!connectDelegate->_done) [runLoop runMode: connectRunLoopMode beforeDate: nil]; /* Cleanup */ [runLoop runMode: connectRunLoopMode beforeDate: [OFDate date]]; _delegate = delegate; if (connectDelegate->_exception != nil) @throw connectDelegate->_exception; objc_autoreleasePoolPop(pool); } - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port { [self asyncConnectToHost: host port: port runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode { void *pool = objc_autoreleasePoolPush(); id <OFTCPSocketDelegate> delegate; if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if (_SOCKS5Host != nil) { delegate = [[[OFTCPSocketSOCKS5Connector alloc] initWithSocket: self host: host port: port |
︙ | ︙ | |||
253 254 255 256 257 258 259 | objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port | | | | | | | 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | objc_autoreleasePoolPop(pool); } #ifdef OF_HAVE_BLOCKS - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port block: (OFTCPSocketAsyncConnectBlock)block { [self asyncConnectToHost: host port: port runLoopMode: OFDefaultRunLoopMode block: block]; } - (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port runLoopMode: (OFRunLoopMode)runLoopMode block: (OFTCPSocketAsyncConnectBlock)block { void *pool = objc_autoreleasePoolPush(); id <OFTCPSocketDelegate> delegate = nil; if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if (_SOCKS5Host != nil) { delegate = [[[OFTCPSocketSOCKS5Connector alloc] initWithSocket: self host: host port: port |
︙ | ︙ | |||
295 296 297 298 299 300 301 | block: (delegate == nil ? block : NULL)] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #endif | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | block: (delegate == nil ? block : NULL)] autorelease] startWithRunLoopMode: runLoopMode]; objc_autoreleasePoolPop(pool); } #endif - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port { const int one = 1; void *pool = objc_autoreleasePoolPush(); OFData *socketAddresses; OFSocketAddress address; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if (_SOCKS5Host != nil) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; socketAddresses = [[OFThread DNSResolver] resolveAddressesForHost: host addressFamily: OFSocketAddressFamilyAny]; address = *(OFSocketAddress *)[socketAddresses itemAtIndex: 0]; OFSocketAddressSetPort(&address, port); if ((_socket = socket(address.sockaddr.sockaddr.sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)) == OFInvalidSocketHandle) @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: OFSocketErrNo()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&one, (socklen_t)sizeof(one)); #if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS) if (port != 0) { #endif if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: errNo]; } #if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS) } else { for (;;) { uint16_t rnd = 0; int ret; while (rnd < 1024) rnd = (uint16_t)rand(); OFSocketAddressSetPort(&address, rnd); if ((ret = bind(_socket, &address.sockaddr.sockaddr, address.length)) == 0) { port = rnd; break; } if (OFSocketErrNo() != EADDRINUSE) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: errNo]; } } } #endif objc_autoreleasePoolPop(pool); if (port > 0) return port; #if !defined(OF_HPUX) && !defined(OF_WII) && !defined(OF_NINTENDO_3DS) memset(&address, 0, sizeof(address)); address.length = (socklen_t)sizeof(address.sockaddr); if (OFGetSockName(_socket, &address.sockaddr.sockaddr, &address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: errNo]; } if (address.sockaddr.sockaddr.sa_family == AF_INET) return OFFromBigEndian16(address.sockaddr.in.sin_port); # ifdef OF_HAVE_IPV6 else if (address.sockaddr.sockaddr.sa_family == AF_INET6) return OFFromBigEndian16(address.sockaddr.in6.sin6_port); # endif else { closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: EAFNOSUPPORT]; } #else closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: EADDRNOTAVAIL]; #endif } #if !defined(OF_WII) && !defined(OF_NINTENDO_3DS) - (void)setSendsKeepAlives: (bool)sendsKeepAlives { int v = sendsKeepAlives; if (setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&v, (socklen_t)sizeof(v)) != 0) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: OFSocketErrNo()]; } - (bool)sendsKeepAlives { int v; socklen_t len = sizeof(v); if (getsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&v, &len) != 0 || len != sizeof(v)) @throw [OFGetOptionFailedException exceptionWithObject: self errNo: OFSocketErrNo()]; return v; } #endif #ifndef OF_WII - (void)setCanDelaySendingSegments: (bool)canDelaySendingSegments { int v = !canDelaySendingSegments; if (setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&v, (socklen_t)sizeof(v)) != 0) @throw [OFSetOptionFailedException exceptionWithObject: self errNo: OFSocketErrNo()]; } - (bool)canDelaySendingSegments { int v; socklen_t len = sizeof(v); if (getsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&v, &len) != 0 || len != sizeof(v)) @throw [OFGetOptionFailedException exceptionWithObject: self errNo: OFSocketErrNo()]; return !v; } #endif - (void)close { |
︙ | ︙ |
Modified src/OFTCPSocketSOCKS5Connector.h from [1461d18ce8] to [a83f3eec6d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | @interface OFTCPSocketSOCKS5Connector: OFObject <OFTCPSocketDelegate> { OFTCPSocket *_socket; OFString *_host; uint16_t _port; id <OFTCPSocketDelegate> _Nullable _delegate; #ifdef OF_HAVE_BLOCKS | | < < < < < < < | | < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | @interface OFTCPSocketSOCKS5Connector: OFObject <OFTCPSocketDelegate> { OFTCPSocket *_socket; OFString *_host; uint16_t _port; id <OFTCPSocketDelegate> _Nullable _delegate; #ifdef OF_HAVE_BLOCKS OFTCPSocketAsyncConnectBlock _Nullable _block; #endif id _Nullable _exception; uint_least8_t _SOCKS5State; /* Longest read is domain name (max 255 bytes) + port */ unsigned char _buffer[257]; OFMutableData *_Nullable _request; } - (instancetype)initWithSocket: (OFTCPSocket *)sock host: (OFString *)host port: (uint16_t)port delegate: (nullable id <OFTCPSocketDelegate>)delegate #ifdef OF_HAVE_BLOCKS block: (nullable OFTCPSocketAsyncConnectBlock)block #endif ; - (void)didConnect; @end OF_ASSUME_NONNULL_END |
Modified src/OFTCPSocketSOCKS5Connector.m from [a4bbcb1257] to [5abece8458].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #import "OFTCPSocketSOCKS5Connector.h" #import "OFData.h" #import "OFRunLoop.h" #import "OFString.h" #import "OFConnectionFailedException.h" @implementation OFTCPSocketSOCKS5Connector - (instancetype)initWithSocket: (OFTCPSocket *)sock host: (OFString *)host port: (uint16_t)port delegate: (id <OFTCPSocketDelegate>)delegate #ifdef OF_HAVE_BLOCKS | > > > > > > > > > | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | #import "OFTCPSocketSOCKS5Connector.h" #import "OFData.h" #import "OFRunLoop.h" #import "OFString.h" #import "OFConnectionFailedException.h" enum { stateSendAuthentication = 1, stateReadVersion, stateSendRequest, stateReadResponse, stateReadAddress, stateReadAddressLength, }; @implementation OFTCPSocketSOCKS5Connector - (instancetype)initWithSocket: (OFTCPSocket *)sock host: (OFString *)host port: (uint16_t)port delegate: (id <OFTCPSocketDelegate>)delegate #ifdef OF_HAVE_BLOCKS block: (OFTCPSocketAsyncConnectBlock)block #endif { self = [super init]; @try { _socket = [sock retain]; _host = [host copy]; |
︙ | ︙ | |||
80 81 82 83 84 85 86 | #ifdef OF_HAVE_BLOCKS if (_block != NULL) _block(_exception); else { #endif if ([_delegate respondsToSelector: @selector(socket:didConnectToHost:port:exception:)]) | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #ifdef OF_HAVE_BLOCKS if (_block != NULL) _block(_exception); else { #endif if ([_delegate respondsToSelector: @selector(socket:didConnectToHost:port:exception:)]) [_delegate socket: _socket didConnectToHost: _host port: _port exception: _exception]; #ifdef OF_HAVE_BLOCKS } #endif } |
︙ | ︙ | |||
102 103 104 105 106 107 108 | if (exception != nil) { _exception = [exception retain]; [self didConnect]; return; } | | < | | | | < | < | < | | < | | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | if (exception != nil) { _exception = [exception retain]; [self didConnect]; return; } data = [OFData dataWithItems: "\x05\x01\x00" count: 3]; _SOCKS5State = stateSendAuthentication; [_socket asyncWriteData: data runLoopMode: [OFRunLoop currentRunLoop].currentMode]; } - (bool)stream: (OFStream *)sock didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (id)exception { OFRunLoopMode runLoopMode; unsigned char *SOCKSVersion; uint8_t hostLength; unsigned char port[2]; unsigned char *response, *addressLength; if (exception != nil) { _exception = [exception retain]; [self didConnect]; return false; } runLoopMode = [OFRunLoop currentRunLoop].currentMode; switch (_SOCKS5State) { case stateReadVersion: SOCKSVersion = buffer; if (SOCKSVersion[0] != 5 || SOCKSVersion[1] != 0) { _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: self errNo: EPROTONOSUPPORT]; [self didConnect]; return false; } [_request release]; _request = [[OFMutableData alloc] init]; [_request addItems: "\x05\x01\x00\x03" count: 4]; hostLength = (uint8_t)_host.UTF8StringLength; [_request addItem: &hostLength]; [_request addItems: _host.UTF8String count: hostLength]; port[0] = _port >> 8; port[1] = _port & 0xFF; [_request addItems: port count: 2]; _SOCKS5State = stateSendRequest; [_socket asyncWriteData: _request runLoopMode: runLoopMode]; return false; case stateReadResponse: response = buffer; if (response[0] != 5 || response[2] != 0) { _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: self |
︙ | ︙ | |||
222 223 224 225 226 227 228 | [self didConnect]; return false; } /* Skip the rest of the response */ switch (response[3]) { case 1: /* IPv4 */ | | | | | | | | | | | | | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | [self didConnect]; return false; } /* Skip the rest of the response */ switch (response[3]) { case 1: /* IPv4 */ _SOCKS5State = stateReadAddress; [_socket asyncReadIntoBuffer: _buffer exactLength: 4 + 2 runLoopMode: runLoopMode]; return false; case 3: /* Domain name */ _SOCKS5State = stateReadAddressLength; [_socket asyncReadIntoBuffer: _buffer exactLength: 1 runLoopMode: runLoopMode]; return false; case 4: /* IPv6 */ _SOCKS5State = stateReadAddress; [_socket asyncReadIntoBuffer: _buffer exactLength: 16 + 2 runLoopMode: runLoopMode]; return false; default: _exception = [[OFConnectionFailedException alloc] initWithHost: _host port: _port socket: self errNo: EPROTONOSUPPORT]; [self didConnect]; return false; } return false; case stateReadAddress: [self didConnect]; return false; case stateReadAddressLength: addressLength = buffer; _SOCKS5State = stateReadAddress; [_socket asyncReadIntoBuffer: _buffer exactLength: addressLength[0] + 2 runLoopMode: runLoopMode]; return false; default: assert(0); return false; } } - (OFData *)stream: (OFStream *)sock didWriteData: (OFData *)data bytesWritten: (size_t)bytesWritten exception: (id)exception { OFRunLoopMode runLoopMode; if (exception != nil) { _exception = [exception retain]; [self didConnect]; return nil; } runLoopMode = [OFRunLoop currentRunLoop].currentMode; switch (_SOCKS5State) { case stateSendAuthentication: _SOCKS5State = stateReadVersion; [_socket asyncReadIntoBuffer: _buffer exactLength: 2 runLoopMode: runLoopMode]; return nil; case stateSendRequest: [_request release]; _request = nil; _SOCKS5State = stateReadResponse; [_socket asyncReadIntoBuffer: _buffer exactLength: 4 runLoopMode: runLoopMode]; return nil; default: assert(0); return nil; } } @end |
Renamed and modified src/tlskey.h [32bd25a13e] to src/OFTLSKey.h [daee12b5cc].
1 | /* | < < | > > | | > > > | | | | | | | | | | | | | > > > > > > > > > > > > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "objfw-defs.h" #include <errno.h> #include "platform.h" #if !defined(OF_HAVE_THREADS) || \ (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS)) # error No thread-local storage available! #endif #import "macros.h" #if defined(OF_HAVE_PTHREADS) # include <pthread.h> typedef pthread_key_t OFTLSKey; #elif defined(OF_WINDOWS) # include <windows.h> typedef DWORD OFTLSKey; #elif defined(OF_MORPHOS) # include <proto/exec.h> typedef ULONG OFTLSKey; #elif defined(OF_AMIGAOS) typedef struct _OFTLSKey { struct objc_hashtable *table; struct _OFTLSKey *next, *previous; } *OFTLSKey; #endif #ifdef __cplusplus extern "C" { #endif extern int OFTLSKeyNew(OFTLSKey *key); extern int OFTLSKeyFree(OFTLSKey key); #ifdef __cplusplus } #endif /* TLS keys are inlined for performance. */ #if defined(OF_HAVE_PTHREADS) static OF_INLINE void * OFTLSKeyGet(OFTLSKey key) { return pthread_getspecific(key); } static OF_INLINE int OFTLSKeySet(OFTLSKey key, void *ptr) { return pthread_setspecific(key, ptr); } #elif defined(OF_WINDOWS) static OF_INLINE void * OFTLSKeyGet(OFTLSKey key) { return TlsGetValue(key); } static OF_INLINE int OFTLSKeySet(OFTLSKey key, void *ptr) { return (TlsSetValue(key, ptr) ? 0 : EINVAL); } #elif defined(OF_MORPHOS) static OF_INLINE void * OFTLSKeyGet(OFTLSKey key) { return (void *)TLSGetValue(key); } static OF_INLINE int OFTLSKeySet(OFTLSKey key, void *ptr) { return (TLSSetValue(key, (APTR)ptr) ? 0 : EINVAL); } #elif defined(OF_AMIGAOS) /* Those are too big too inline. */ # ifdef __cplusplus extern "C" { # endif extern void *OFTLSKeyGet(OFTLSKey key); extern int OFTLSKeySet(OFTLSKey key, void *ptr); # ifdef __cplusplus } # endif #endif |
Renamed and modified src/tlskey.m [abedce4e93] to src/OFTLSKey.m [e3604d121c].
1 | /* | < < | | | > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #if defined(OF_HAVE_PTHREADS) # include "platform/POSIX/OFTLSKey.m" #elif defined(OF_WINDOWS) # include "platform/Windows/OFTLSKey.m" #elif defined(OF_MORPHOS) # include "platform/MorphOS/OFTLSKey.m" #elif defined(OF_AMIGAOS) # include "platform/AmigaOS/OFTLSKey.m" #endif |
Renamed and modified src/OFTLSSocket.h [c7eec148cd] to src/OFTLSStream.h [0ae2a154e2].
1 | /* | < < | | > | < < < | | < < < < | < | < < < | < > > > > > < < < < < < < < | < | | | > > > > > > > > > | < < < < > | < | < < | > | < > > > > > > | | | | | < < > | < < | > | > < | | > > | > > > > > < > > | | < < > | | < < < | | | | < < > < | | < < < | > | | | | > | > > | | | < < < | | | | | < < < | > < | < < < | < < < | > | > > | | < > > | | > | < > > > | < | > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFStream.h" #import "OFRunLoop.h" OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFTLSStream; /** * @brief An enum representing an error of an OFTLSStream. */ typedef enum { /** @brief An unknown error. */ OFTLSStreamErrorCodeUnknown, /** @brief Initialization of the TLS context failed. */ OFTLSStreamErrorCodeInitializationFailed } OFTLSStreamErrorCode; /** * @protocol OFTLSStreamDelegate OFTLSStream.h ObjFW/OFTLSStream.h * * A delegate for OFTLSStream. */ @protocol OFTLSStreamDelegate <OFStreamDelegate> /** * @brief A method which is called when a TLS stream performed the client * handshake. * * @param stream The TLS stream which performed the handshake * @param host The host for which the handshake was performed * @param exception An exception that occurred during the handshake, or nil on * success */ - (void)stream: (OFTLSStream *)stream didPerformClientHandshakeWithHost: (OFString *)host exception: (nullable id)exception; @end /** * @class OFTLSStream OFTLSStream.h ObjFW/OFTLSStream.h * * @brief A class that provides Transport Layer Security on top of a stream. * * This class is a class cluster and returns a suitable OFTLSStream subclass, * if available. * * Subclasses need to override @ref lowlevelReadIntoBuffer:length:, * @ref lowlevelWriteBuffer:length: and * @ref asyncPerformClientHandshakeWithHost:runLoopMode:. The method * @ref hasDataInReadBuffer should be overridden to return `true` if the TLS * stream has cached unprocessed data internally, while returning * `self.underlyingStream.hasDataInReadBuffer` if it does not have any * unprocessed data. In order to get access to the underlying stream, * @ref underlyingStream can be used. */ @interface OFTLSStream: OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> { OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *_underlyingStream; bool _verifiesCertificates; OF_RESERVE_IVARS(OFTLSStream, 4) } /** * @brief The underlying stream. */ @property (readonly, nonatomic) OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *underlyingStream; /** * @brief The delegate for asynchronous operations on the stream. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id <OFTLSStreamDelegate> delegate; /** * @brief Whether certificates are verified. Default is true. */ @property (nonatomic) bool verifiesCertificates; - (instancetype)init OF_UNAVAILABLE; /** * @brief Creates a new TLS stream with the specified stream as its underlying * stream. * * @param stream The stream to use as underlying stream. Must not be closed * before the TLS stream is closed. * @return A new, autoreleased TLS stream */ + (instancetype)streamWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream; /** * @brief Initializes the TLS stream with the specified stream as its * underlying stream. * * @param stream The stream to use as underlying stream. Must not be closed * before the TLS stream is closed. * @return An initialized TLS stream */ - (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream OF_DESIGNATED_INITIALIZER; /** * @brief Asynchronously performs the TLS client handshake for the specified * host and calls the delegate afterwards. * * @param host The host to perform the handshake with */ - (void)asyncPerformClientHandshakeWithHost: (OFString *)host; /** * @brief Asynchronously performs the TLS client handshake for the specified * host and calls the delegate afterwards. * * @param host The host to perform the handshake with * @param runLoopMode The run loop mode in which to perform the async handshake */ - (void)asyncPerformClientHandshakeWithHost: (OFString *)host runLoopMode: (OFRunLoopMode)runLoopMode; /** * @brief Performs the TLS client handshake for the specified host. * * @param host The host to perform the handshake with */ - (void)performClientHandshakeWithHost: (OFString *)host; @end #ifdef __cplusplus extern "C" { #endif /** * @brief The implementation for OFTLSStream to use. * * This can be set to a class that is always used for OFTLSStream. This is * useful to either force a specific implementation or use one that ObjFW does * not know about. */ extern Class OFTLSStreamImplementation; /** * @brief Returns a string description for the TLS stream error code. * * @param errorCode The error code to return the description for * @return A string description for the TLS stream error code */ extern OFString *OFTLSStreamErrorCodeDescription( OFTLSStreamErrorCode errorCode); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Added src/OFTLSStream.m version [01bd29e506].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFTLSStream.h" #import "OFDate.h" #import "OFNotImplementedException.h" #import "OFTLSHandshakeFailedException.h" @interface OFTLSStreamHandshakeDelegate: OFObject <OFTLSStreamDelegate> { @public bool _done; id _exception; } @end Class OFTLSStreamImplementation = Nil; static const OFRunLoopMode handshakeRunLoopMode = @"OFTLSStreamHandshakeRunLoopMode"; /* * References to exceptions. This is needed because they are only used by * subclasses that are in a different library. */ void _references_to_exceptions_of_OFTLSStream(void) { _OFTLSHandshakeFailedException_reference = 1; } OFString * OFTLSStreamErrorCodeDescription(OFTLSStreamErrorCode errorCode) { switch (errorCode) { case OFTLSStreamErrorCodeInitializationFailed: return @"Initialization of TLS context failed"; default: return @"Unknown error"; } } @implementation OFTLSStreamHandshakeDelegate - (void)dealloc { [_exception release]; [super dealloc]; } - (void)stream: (OFTLSStream *)stream didPerformClientHandshakeWithHost: (OFString *)host exception: (id)exception { _done = true; _exception = [exception retain]; } @end @implementation OFTLSStream @synthesize underlyingStream = _underlyingStream; @dynamic delegate; @synthesize verifiesCertificates = _verifiesCertificates; + (instancetype)alloc { if (self == [OFTLSStream class]) { if (OFTLSStreamImplementation != Nil) return [OFTLSStreamImplementation alloc]; @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; } return [super alloc]; } + (instancetype)streamWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream { return [[[self alloc] initWithStream: stream] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream { self = [super init]; @try { _underlyingStream = [stream retain]; _verifiesCertificates = true; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_underlyingStream release]; [super dealloc]; } - (void)close { [_underlyingStream release]; _underlyingStream = nil; [super close]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { OF_UNRECOGNIZED_SELECTOR } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { OF_UNRECOGNIZED_SELECTOR } - (bool)hasDataInReadBuffer { return (super.hasDataInReadBuffer || _underlyingStream.hasDataInReadBuffer); } - (bool)lowlevelIsAtEndOfStream { return _underlyingStream.atEndOfStream; } - (int)fileDescriptorForReading { return _underlyingStream.fileDescriptorForReading; } - (int)fileDescriptorForWriting { return _underlyingStream.fileDescriptorForWriting; } - (void)asyncPerformClientHandshakeWithHost: (OFString *)host { [self asyncPerformClientHandshakeWithHost: host runLoopMode: OFDefaultRunLoopMode]; } - (void)asyncPerformClientHandshakeWithHost: (OFString *)host runLoopMode: (OFRunLoopMode)runLoopMode { OF_UNRECOGNIZED_SELECTOR } - (void)performClientHandshakeWithHost: (OFString *)host { void *pool = objc_autoreleasePoolPush(); id <OFTLSStreamDelegate> delegate = _delegate; OFTLSStreamHandshakeDelegate *handshakeDelegate = [[[OFTLSStreamHandshakeDelegate alloc] init] autorelease]; OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; _delegate = handshakeDelegate; [self asyncPerformClientHandshakeWithHost: host runLoopMode: handshakeRunLoopMode]; while (!handshakeDelegate->_done) [runLoop runMode: handshakeRunLoopMode beforeDate: nil]; /* Cleanup */ [runLoop runMode: handshakeRunLoopMode beforeDate: [OFDate date]]; _delegate = delegate; if (handshakeDelegate->_exception != nil) @throw handshakeDelegate->_exception; objc_autoreleasePoolPop(pool); } @end |
Modified src/OFTarArchive.h from [7e4a70a4fc] to [a9bc537672].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | * * @brief A class for accessing and manipulating tar archives. */ OF_SUBCLASSING_RESTRICTED @interface OFTarArchive: OFObject { OFStream *_stream; | | | | | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | * * @brief A class for accessing and manipulating tar archives. */ OF_SUBCLASSING_RESTRICTED @interface OFTarArchive: OFObject { OFStream *_stream; enum OFTarArchiveMode { OFTarArchiveModeRead, OFTarArchiveModeWrite, OFTarArchiveModeAppend } _mode; OFStringEncoding _encoding; OFStream *_Nullable _lastReturnedStream; } /** * @brief The encoding to use for the archive. Defaults to UTF-8. */ @property (nonatomic) OFStringEncoding encoding; /** * @brief A stream for reading the current entry. * * @note This is only available in read mode. * * @note The returned stream conforms to @ref OFReadyForReadingObserving if the |
︙ | ︙ | |||
63 64 65 66 67 68 69 | * @param stream A stream from which the tar archive will be read. * For append mode, this needs to be an OFSeekableStream. * @param mode The mode for the tar file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFTarArchive */ | | < | < | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | * @param stream A stream from which the tar archive will be read. * For append mode, this needs to be an OFSeekableStream. * @param mode The mode for the tar file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFTarArchive */ + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode; #ifdef OF_HAVE_FILES /** * @brief Creates a new OFTarArchive object with the specified file. * * @param path The path to the tar archive * @param mode The mode for the tar file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFTarArchive */ + (instancetype)archiveWithPath: (OFString *)path mode: (OFString *)mode; #endif - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFTarArchive object with the * specified stream. |
︙ | ︙ | |||
107 108 109 110 111 112 113 | * * @param path The path to the tar archive * @param mode The mode for the tar file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFTarArchive */ | | < | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | * * @param path The path to the tar archive * @param mode The mode for the tar file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFTarArchive */ - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode; #endif /** * @brief Returns the next entry from the tar archive or `nil` if all entries * have been read. * * @note This is only available in read mode. |
︙ | ︙ |
Modified src/OFTarArchive.m from [6889b3aa0d] to [5a61b65e4b].
1 | /* | < < | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFTarArchive.h" #import "OFTarArchiveEntry.h" #import "OFTarArchiveEntry+Private.h" #import "OFDate.h" #import "OFSeekableStream.h" #import "OFStream.h" |
︙ | ︙ | |||
59 60 61 62 63 64 65 | - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry; @end @implementation OFTarArchive: OFObject @synthesize encoding = _encoding; | | < | < | < | < | < | | | | | < | | < | < | < | < | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | - (instancetype)of_initWithStream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry; @end @implementation OFTarArchive: OFObject @synthesize encoding = _encoding; + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode { return [[[self alloc] initWithStream: stream mode: mode] autorelease]; } #ifdef OF_HAVE_FILES + (instancetype)archiveWithPath: (OFString *)path mode: (OFString *)mode { return [[[self alloc] initWithPath: path mode: mode] autorelease]; } #endif - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode { self = [super init]; @try { _stream = [stream retain]; if ([mode isEqual: @"r"]) _mode = OFTarArchiveModeRead; else if ([mode isEqual: @"w"]) _mode = OFTarArchiveModeWrite; else if ([mode isEqual: @"a"]) _mode = OFTarArchiveModeAppend; else @throw [OFInvalidArgumentException exception]; if (_mode == OFTarArchiveModeAppend) { uint32_t buffer[1024 / sizeof(uint32_t)]; bool empty = true; if (![_stream isKindOfClass: [OFSeekableStream class]]) @throw [OFInvalidArgumentException exception]; [(OFSeekableStream *)_stream seekToOffset: -1024 whence: SEEK_END]; [_stream readIntoBuffer: buffer exactLength: 1024]; for (size_t i = 0; i < 1024 / sizeof(uint32_t); i++) if (buffer[i] != 0) empty = false; if (!empty) @throw [OFInvalidFormatException exception]; [(OFSeekableStream *)stream seekToOffset: -1024 whence: SEEK_END]; } _encoding = OFStringEncodingUTF8; } @catch (id e) { [self release]; @throw e; } return self; } #ifdef OF_HAVE_FILES - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode { OFFile *file; if ([mode isEqual: @"a"]) file = [[OFFile alloc] initWithPath: path mode: @"r+"]; else file = [[OFFile alloc] initWithPath: path mode: mode]; @try { self = [self initWithStream: file mode: mode]; } @finally { [file release]; } return self; } #endif |
︙ | ︙ | |||
166 167 168 169 170 171 172 | - (OFTarArchiveEntry *)nextEntry { OFTarArchiveEntry *entry; uint32_t buffer[512 / sizeof(uint32_t)]; bool empty = true; | | | < | < | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | - (OFTarArchiveEntry *)nextEntry { OFTarArchiveEntry *entry; uint32_t buffer[512 / sizeof(uint32_t)]; bool empty = true; if (_mode != OFTarArchiveModeRead) @throw [OFInvalidArgumentException exception]; [(OFTarArchiveFileReadStream *)_lastReturnedStream of_skip]; @try { [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ } [_lastReturnedStream release]; _lastReturnedStream = nil; if (_stream.atEndOfStream) return nil; [_stream readIntoBuffer: buffer exactLength: 512]; for (size_t i = 0; i < 512 / sizeof(uint32_t); i++) if (buffer[i] != 0) empty = false; if (empty) { [_stream readIntoBuffer: buffer exactLength: 512]; for (size_t i = 0; i < 512 / sizeof(uint32_t); i++) if (buffer[i] != 0) @throw [OFInvalidFormatException exception]; return nil; } |
︙ | ︙ | |||
212 213 214 215 216 217 218 | entry: entry]; return entry; } - (OFStream *)streamForReadingCurrentEntry { | | | < | < | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | entry: entry]; return entry; } - (OFStream *)streamForReadingCurrentEntry { if (_mode != OFTarArchiveModeRead) @throw [OFInvalidArgumentException exception]; if (_lastReturnedStream == nil) @throw [OFInvalidArgumentException exception]; return [[(OFTarArchiveFileReadStream *)_lastReturnedStream retain] autorelease]; } - (OFStream *)streamForWritingEntry: (OFTarArchiveEntry *)entry { void *pool; if (_mode != OFTarArchiveModeWrite && _mode != OFTarArchiveModeAppend) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); @try { [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ } [_lastReturnedStream release]; _lastReturnedStream = nil; [entry of_writeToStream: _stream encoding: _encoding]; _lastReturnedStream = [[OFTarArchiveFileWriteStream alloc] of_initWithStream: _stream entry: entry]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
266 267 268 269 270 271 272 | [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ } [_lastReturnedStream release]; _lastReturnedStream = nil; | | < | < | 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ } [_lastReturnedStream release]; _lastReturnedStream = nil; if (_mode == OFTarArchiveModeWrite || _mode == OFTarArchiveModeAppend) { char buffer[1024]; memset(buffer, '\0', 1024); [_stream writeBuffer: buffer length: 1024]; } [_stream release]; _stream = nil; } @end |
︙ | ︙ | |||
326 327 328 329 330 331 332 | if (length > UINT64_MAX) @throw [OFOutOfRangeException exception]; #endif if ((uint64_t)length > _toRead) length = (size_t)_toRead; | | < < | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | if (length > UINT64_MAX) @throw [OFOutOfRangeException exception]; #endif if ((uint64_t)length > _toRead) length = (size_t)_toRead; ret = [_stream readIntoBuffer: buffer length: length]; if (ret == 0) _atEndOfStream = true; _toRead -= ret; return ret; } |
︙ | ︙ | |||
375 376 377 378 379 380 381 | - (void)of_skip { if (_stream == nil || _skipped) return; if ([_stream isKindOfClass: [OFSeekableStream class]] && | | | | < | 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 | - (void)of_skip { if (_stream == nil || _skipped) return; if ([_stream isKindOfClass: [OFSeekableStream class]] && _toRead <= INT64_MAX && (OFFileOffset)_toRead == (int64_t)_toRead) { uint64_t size; [(OFSeekableStream *)_stream seekToOffset: (OFFileOffset)_toRead whence: SEEK_CUR]; _toRead = 0; size = _entry.size; if (size % 512 != 0) [(OFSeekableStream *)_stream seekToOffset: 512 - (size % 512) whence: SEEK_CUR]; } else { char buffer[512]; uint64_t size; while (_toRead >= 512) { [_stream readIntoBuffer: buffer exactLength: 512]; _toRead -= 512; } if (_toRead > 0) { [_stream readIntoBuffer: buffer exactLength: (size_t)_toRead]; _toRead = 0; |
︙ | ︙ | |||
444 445 446 447 448 449 450 | [self close]; [_entry release]; [super dealloc]; } | | < < < | < > > > > > > | | | 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | [self close]; [_entry release]; [super dealloc]; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if ((uint64_t)length > _toWrite) @throw [OFOutOfRangeException exception]; @try { [_stream writeBuffer: buffer length: length]; } @catch (OFWriteFailedException *e) { OFEnsure(e.bytesWritten <= length); _toWrite -= e.bytesWritten; if (e.errNo == EWOULDBLOCK || e.errNo == EAGAIN) return e.bytesWritten; @throw e; } _toWrite -= length; return length; } - (bool)lowlevelIsAtEndOfStream { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; |
︙ | ︙ |
Modified src/OFTarArchiveEntry+Private.h from [13ddd96cdf] to [92ff63bc6f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | OF_ASSUME_NONNULL_BEGIN @class OFStream; OF_DIRECT_MEMBERS @interface OFTarArchiveEntry () - (instancetype)of_initWithHeader: (unsigned char [_Nonnull 512])header | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | OF_ASSUME_NONNULL_BEGIN @class OFStream; OF_DIRECT_MEMBERS @interface OFTarArchiveEntry () - (instancetype)of_initWithHeader: (unsigned char [_Nonnull 512])header encoding: (OFStringEncoding)encoding OF_METHOD_FAMILY(init); - (void)of_writeToStream: (OFStream *)stream encoding: (OFStringEncoding)encoding; @end OF_ASSUME_NONNULL_END |
Modified src/OFTarArchiveEntry.h from [05098921c4] to [68a10bc9a2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | /** @file */ @class OFDate; /** * @brief The type of the archive entry. */ | | | | | | | | | | | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | /** @file */ @class OFDate; /** * @brief The type of the archive entry. */ typedef enum { /** Normal file */ OFTarArchiveEntryTypeFile = '0', /** Hard link */ OFTarArchiveEntryTypeLink = '1', /** Symbolic link */ OFTarArchiveEntryTypeSymlink = '2', /** Character device */ OFTarArchiveEntryTypeCharacterDevice = '3', /** Block device */ OFTarArchiveEntryTypeBlockDevice = '4', /** Directory */ OFTarArchiveEntryTypeDirectory = '5', /** FIFO */ OFTarArchiveEntryTypeFIFO = '6', /** Contiguous file */ OFTarArchiveEntryTypeContiguousFile = '7', } OFTarArchiveEntryType; /** * @class OFTarArchiveEntry OFTarArchiveEntry.h ObjFW/OFTarArchiveEntry.h * * @brief A class which represents an entry of a tar archive. */ @interface OFTarArchiveEntry: OFObject <OFCopying, OFMutableCopying> { OFString *_fileName; unsigned long _mode; unsigned long long _size; unsigned long _UID, _GID; OFDate *_modificationDate; OFTarArchiveEntryType _type; OFString *_Nullable _targetFileName; OFString *_Nullable _owner, *_Nullable _group; unsigned long _deviceMajor, _deviceMinor; OF_RESERVE_IVARS(OFTarArchiveEntry, 4) } /** |
︙ | ︙ | |||
93 94 95 96 97 98 99 | * @brief The date of the last modification of the file. */ @property (readonly, retain, nonatomic) OFDate *modificationDate; /** * @brief The type of the archive entry. * | | | | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | * @brief The date of the last modification of the file. */ @property (readonly, retain, nonatomic) OFDate *modificationDate; /** * @brief The type of the archive entry. * * See @ref OFTarArchiveEntryType. */ @property (readonly, nonatomic) OFTarArchiveEntryType type; /** * @brief The file name of the target (for a hard link or symbolic link). */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *targetFileName; |
︙ | ︙ |
Modified src/OFTarArchiveEntry.m from [5e09222260] to [1a8a203480].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | #import "OFStream.h" #import "OFString.h" #import "OFOutOfRangeException.h" static OFString * stringFromBuffer(const unsigned char *buffer, size_t length, | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #import "OFStream.h" #import "OFString.h" #import "OFOutOfRangeException.h" static OFString * stringFromBuffer(const unsigned char *buffer, size_t length, OFStringEncoding encoding) { for (size_t i = 0; i < length; i++) if (buffer[i] == '\0') length = i; return [OFString stringWithCString: (const char *)buffer encoding: encoding length: length]; } static void stringToBuffer(unsigned char *buffer, OFString *string, size_t length, OFStringEncoding encoding) { size_t cStringLength = [string cStringLengthWithEncoding: encoding]; if (cStringLength > length) @throw [OFOutOfRangeException exception]; memcpy(buffer, [string cStringWithEncoding: encoding], cStringLength); |
︙ | ︙ | |||
63 64 65 66 67 68 69 | return 0; if (buffer[0] == 0x80) { for (size_t i = 1; i < length; i++) value = (value << 8) | buffer[i]; } else value = [stringFromBuffer(buffer, length, | | | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | return 0; if (buffer[0] == 0x80) { for (size_t i = 1; i < length; i++) value = (value << 8) | buffer[i]; } else value = [stringFromBuffer(buffer, length, OFStringEncodingASCII) unsignedLongLongValueWithBase: 8]; if (value > max) @throw [OFOutOfRangeException exception]; return value; } @implementation OFTarArchiveEntry + (instancetype)entryWithFileName: (OFString *)fileName { return [[[self alloc] initWithFileName: fileName] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)of_initWithHeader: (unsigned char [512])header encoding: (OFStringEncoding)encoding { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFString *targetFileName; _fileName = [stringFromBuffer(header, 100, encoding) copy]; _mode = (unsigned long)octalValueFromBuffer( header + 100, 8, ULONG_MAX); _UID = (unsigned long)octalValueFromBuffer( header + 108, 8, ULONG_MAX); _GID = (unsigned long)octalValueFromBuffer( header + 116, 8, ULONG_MAX); _size = (unsigned long long)octalValueFromBuffer( header + 124, 12, ULLONG_MAX); _modificationDate = [[OFDate alloc] initWithTimeIntervalSince1970: (OFTimeInterval)octalValueFromBuffer( header + 136, 12, ULLONG_MAX)]; _type = header[156]; targetFileName = stringFromBuffer(header + 157, 100, encoding); if (targetFileName.length > 0) _targetFileName = [targetFileName copy]; if (_type == '\0') _type = OFTarArchiveEntryTypeFile; if (memcmp(header + 257, "ustar\0" "00", 8) == 0) { OFString *prefix; _owner = [stringFromBuffer(header + 265, 32, encoding) copy]; _group = [stringFromBuffer(header + 297, 32, encoding) |
︙ | ︙ | |||
151 152 153 154 155 156 157 | - (instancetype)initWithFileName: (OFString *)fileName { self = [super init]; @try { _fileName = [fileName copy]; | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | - (instancetype)initWithFileName: (OFString *)fileName { self = [super init]; @try { _fileName = [fileName copy]; _type = OFTarArchiveEntryTypeFile; _mode = 0644; } @catch (id e) { [self release]; @throw e; } return self; |
︙ | ︙ | |||
230 231 232 233 234 235 236 | } - (OFDate *)modificationDate { return _modificationDate; } | | | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | } - (OFDate *)modificationDate { return _modificationDate; } - (OFTarArchiveEntryType)type { return _type; } - (OFString *)targetFileName { return _targetFileName; |
︙ | ︙ | |||
288 289 290 291 292 293 294 | objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (void)of_writeToStream: (OFStream *)stream | | | | | | | | | | | < | 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (void)of_writeToStream: (OFStream *)stream encoding: (OFStringEncoding)encoding { unsigned char buffer[512]; unsigned long long modificationDate; uint16_t checksum = 0; stringToBuffer(buffer, _fileName, 100, encoding); stringToBuffer(buffer + 100, [OFString stringWithFormat: @"%06" PRIo16 " ", _mode], 8, OFStringEncodingASCII); stringToBuffer(buffer + 108, [OFString stringWithFormat: @"%06" PRIo16 " ", _UID], 8, OFStringEncodingASCII); stringToBuffer(buffer + 116, [OFString stringWithFormat: @"%06" PRIo16 " ", _GID], 8, OFStringEncodingASCII); stringToBuffer(buffer + 124, [OFString stringWithFormat: @"%011" PRIo64 " ", _size], 12, OFStringEncodingASCII); modificationDate = _modificationDate.timeIntervalSince1970; stringToBuffer(buffer + 136, [OFString stringWithFormat: @"%011llo", modificationDate], 12, OFStringEncodingASCII); /* * During checksumming, the checksum field is expected to be set to 8 * spaces. */ memset(buffer + 148, ' ', 8); buffer[156] = _type; stringToBuffer(buffer + 157, _targetFileName, 100, encoding); /* ustar */ memcpy(buffer + 257, "ustar\0" "00", 8); stringToBuffer(buffer + 265, _owner, 32, encoding); stringToBuffer(buffer + 297, _group, 32, encoding); stringToBuffer(buffer + 329, [OFString stringWithFormat: @"%06" PRIo32 " ", _deviceMajor], 8, OFStringEncodingASCII); stringToBuffer(buffer + 337, [OFString stringWithFormat: @"%06" PRIo32 " ", _deviceMinor], 8, OFStringEncodingASCII); memset(buffer + 345, '\0', 155 + 12); /* Fill in the checksum */ for (size_t i = 0; i < 500; i++) checksum += buffer[i]; stringToBuffer(buffer + 148, [OFString stringWithFormat: @"%06" PRIo16, checksum], 7, OFStringEncodingASCII); [stream writeBuffer: buffer length: sizeof(buffer)]; } @end |
Modified src/OFThread+Private.h from [5ab3745dfa] to [b87af72459].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFThread.h from [a47e26d1ae] to [edfcfa680d].
1 | /* | < < | < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include <setjmp.h> #import "OFObject.h" #ifdef OF_HAVE_THREADS # import "OFPlainThread.h" #endif OF_ASSUME_NONNULL_BEGIN /** @file */ @class OFDate; #ifdef OF_HAVE_SOCKETS @class OFDNSResolver; #endif @class OFRunLoop; @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); #if defined(OF_HAVE_THREADS) && defined(OF_HAVE_BLOCKS) /** * @brief A block to be executed in a new thread. * * @return The object which should be returned when the thread is joined */ typedef id _Nullable (^OFThreadBlock)(void); #endif /** * @class OFThread OFThread.h ObjFW/OFThread.h * * @brief A class which provides portable threads. * |
︙ | ︙ | |||
62 63 64 65 66 67 68 | * so context can be associated with a thread. */ @interface OFThread: OFObject #ifdef OF_HAVE_THREADS <OFCopying> { @private | | | | | | | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | * so context can be associated with a thread. */ @interface OFThread: OFObject #ifdef OF_HAVE_THREADS <OFCopying> { @private OFPlainThread _thread; OFPlainThreadAttributes _attr; enum OFThreadState { OFThreadStateNotRunning, OFThreadStateRunning, OFThreadStateWaitingForJoin } _running; # ifndef OF_OBJFW_RUNTIME void *_pool; # endif # ifdef OF_HAVE_BLOCKS OFThreadBlock _Nullable _threadBlock; # endif jmp_buf _exitEnv; id _returnValue; bool _supportsSockets; OFRunLoop *_Nullable _runLoop; OFMutableDictionary *_threadDictionary; OFString *_Nullable _name; |
︙ | ︙ | |||
117 118 119 120 121 122 123 | */ @property OF_NULLABLE_PROPERTY (copy) OFString *name; # ifdef OF_HAVE_BLOCKS /** * @brief The block to execute in the thread. */ | | < | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | */ @property OF_NULLABLE_PROPERTY (copy) OFString *name; # ifdef OF_HAVE_BLOCKS /** * @brief The block to execute in the thread. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFThreadBlock threadBlock; # endif /** * @brief The run loop for the thread. */ @property (readonly, nonatomic) OFRunLoop *runLoop; |
︙ | ︙ | |||
167 168 169 170 171 172 173 | # ifdef OF_HAVE_BLOCKS /** * @brief Creates a new thread with the specified block. * * @param threadBlock A block which is executed by the thread * @return A new, autoreleased thread */ | | | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | # ifdef OF_HAVE_BLOCKS /** * @brief Creates a new thread with the specified block. * * @param threadBlock A block which is executed by the thread * @return A new, autoreleased thread */ + (instancetype)threadWithThreadBlock: (OFThreadBlock)threadBlock; # endif /** * @brief Returns the current thread. * * @return The current thread */ |
︙ | ︙ | |||
215 216 217 218 219 220 221 | /** * @brief Suspends execution of the current thread for the specified time * interval. * * @param timeInterval The number of seconds to sleep */ | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | /** * @brief Suspends execution of the current thread for the specified time * interval. * * @param timeInterval The number of seconds to sleep */ + (void)sleepForTimeInterval: (OFTimeInterval)timeInterval; /** * @brief Suspends execution of the current thread until the specified date. * * @param date The date to wait for */ + (void)sleepUntilDate: (OFDate *)date; |
︙ | ︙ | |||
267 268 269 270 271 272 273 | # ifdef OF_HAVE_BLOCKS /** * @brief Initializes an already allocated thread with the specified block. * * @param threadBlock A block which is executed by the thread * @return An initialized OFThread. */ | | | 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | # ifdef OF_HAVE_BLOCKS /** * @brief Initializes an already allocated thread with the specified block. * * @param threadBlock A block which is executed by the thread * @return An initialized OFThread. */ - (instancetype)initWithThreadBlock: (OFThreadBlock)threadBlock; # endif /** * @brief The main routine of the thread. You need to reimplement this! * * @return The object the join method should return when called for this thread */ |
︙ | ︙ |
Modified src/OFThread.m from [690c42ccaa] to [9e6c736b19].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #ifdef OF_NINTENDO_3DS # include <3ds/svc.h> #endif #import "OFThread.h" #import "OFThread+Private.h" #import "OFDate.h" #import "OFDictionary.h" #ifdef OF_HAVE_SOCKETS # import "OFDNSResolver.h" #endif #import "OFLocale.h" #import "OFRunLoop.h" | > > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #ifdef OF_NINTENDO_3DS # include <3ds/svc.h> #endif #import "OFThread.h" #import "OFThread+Private.h" #ifdef OF_HAVE_ATOMIC_OPS # import "OFAtomic.h" #endif #import "OFDate.h" #import "OFDictionary.h" #ifdef OF_HAVE_SOCKETS # import "OFDNSResolver.h" #endif #import "OFLocale.h" #import "OFRunLoop.h" |
︙ | ︙ | |||
75 76 77 78 79 80 81 | #import "OFOutOfRangeException.h" #ifdef OF_HAVE_THREADS # import "OFThreadJoinFailedException.h" # import "OFThreadStartFailedException.h" # import "OFThreadStillRunningException.h" #endif | | | > | | | | | | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #import "OFOutOfRangeException.h" #ifdef OF_HAVE_THREADS # import "OFThreadJoinFailedException.h" # import "OFThreadStartFailedException.h" # import "OFThreadStillRunningException.h" #endif #ifdef OF_MINT /* freemint-gcc does not have trunc() */ # define trunc(x) ((int64_t)(x)) #endif #if defined(OF_HAVE_THREADS) # import "OFTLSKey.h" # if defined(OF_AMIGAOS) && defined(OF_HAVE_SOCKETS) # import "OFSocket.h" # endif static OFTLSKey threadSelfKey; static OFThread *mainThread; #elif defined(OF_HAVE_SOCKETS) static OFDNSResolver *DNSResolver; #endif @implementation OFThread #ifdef OF_HAVE_THREADS static void callMain(id object) { OFThread *thread = (OFThread *)object; OFString *name; if (OFTLSKeySet(threadSelfKey, thread) != 0) @throw [OFInitializationFailedException exceptionWithClass: thread.class]; #ifndef OF_OBJFW_RUNTIME thread->_pool = objc_autoreleasePoolPush(); #endif name = thread.name; if (name != nil) OFSetThreadName( [name cStringWithEncoding: [OFLocale encoding]]); else OFSetThreadName(object_getClassName(thread)); #if defined(OF_AMIGAOS) && defined(OF_HAVE_SOCKETS) if (thread.supportsSockets) if (!OFSocketInit()) @throw [OFInitializationFailedException exceptionWithClass: thread.class]; #endif /* * Nasty workaround for thread implementations which can't return a * pointer on join, or don't have a way to exit a thread. |
︙ | ︙ | |||
142 143 144 145 146 147 148 | #ifdef OF_OBJFW_RUNTIME objc_autoreleasePoolPop((void *)(uintptr_t)-1); #else objc_autoreleasePoolPop(thread->_pool); #endif | | | | | | | | | | | > > > > > > > > > > > < < < < < | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | #ifdef OF_OBJFW_RUNTIME objc_autoreleasePoolPop((void *)(uintptr_t)-1); #else objc_autoreleasePoolPop(thread->_pool); #endif #if defined(OF_AMIGAOS) && !defined(OF_MORPHOS) && defined(OF_HAVE_SOCKETS) if (thread.supportsSockets) OFSocketDeinit(); #endif thread->_running = OFThreadStateWaitingForJoin; [thread release]; } @synthesize name = _name; # ifdef OF_HAVE_BLOCKS @synthesize threadBlock = _threadBlock; # endif + (void)initialize { if (self != [OFThread class]) return; if (OFTLSKeyNew(&threadSelfKey) != 0) @throw [OFInitializationFailedException exceptionWithClass: self]; } + (instancetype)thread { return [[[self alloc] init] autorelease]; } # ifdef OF_HAVE_BLOCKS + (instancetype)threadWithThreadBlock: (OFThreadBlock)threadBlock { return [[[self alloc] initWithThreadBlock: threadBlock] autorelease]; } # endif + (OFThread *)currentThread { return OFTLSKeyGet(threadSelfKey); } + (OFThread *)mainThread { return mainThread; } + (bool)isMainThread { if (mainThread == nil) return false; return (OFTLSKeyGet(threadSelfKey) == mainThread); } + (OFMutableDictionary *)threadDictionary { OFThread *thread = OFTLSKeyGet(threadSelfKey); if (thread == nil) return nil; if (thread->_threadDictionary == nil) thread->_threadDictionary = [[OFMutableDictionary alloc] init]; return thread->_threadDictionary; } #endif #ifdef OF_HAVE_SOCKETS + (OFDNSResolver *)DNSResolver { # ifdef OF_HAVE_THREADS OFThread *thread = OFTLSKeyGet(threadSelfKey); if (thread == nil) return nil; if (thread->_DNSResolver == nil) thread->_DNSResolver = [[OFDNSResolver alloc] init]; return thread->_DNSResolver; # else if (DNSResolver == nil) DNSResolver = [[OFDNSResolver alloc] init]; return DNSResolver; # endif } #endif + (void)sleepForTimeInterval: (OFTimeInterval)timeInterval { if (timeInterval < 0) return; #if defined(OF_WINDOWS) if (timeInterval * 1000 > UINT_MAX) @throw [OFOutOfRangeException exception]; Sleep((unsigned int)(timeInterval * 1000)); #elif defined(OF_NINTENDO_3DS) if (timeInterval * 1000000000 > INT64_MAX) @throw [OFOutOfRangeException exception]; svcSleepThread((int64_t)(timeInterval * 1000000000)); #elif defined(OF_AMIGAOS) struct timerequest request = *DOSBase->dl_TimeReq; request.tr_node.io_Message.mn_ReplyPort = &((struct Process *)FindTask(NULL))->pr_MsgPort; request.tr_node.io_Command = TR_ADDREQUEST; request.tr_time.tv_secs = (ULONG)timeInterval; request.tr_time.tv_micro = (ULONG) ((timeInterval - (unsigned int)timeInterval) * 1000000); DoIO((struct IORequest *)&request); #elif defined(HAVE_NANOSLEEP) struct timespec rqtp; rqtp.tv_sec = (time_t)timeInterval; rqtp.tv_nsec = (long)((timeInterval - rqtp.tv_sec) * 1000000000); if (rqtp.tv_sec != trunc(timeInterval)) @throw [OFOutOfRangeException exception]; nanosleep(&rqtp, NULL); #elif defined(OF_NINTENDO_DS) uint64_t counter; if (timeInterval > UINT64_MAX / 60) @throw [OFOutOfRangeException exception]; counter = timeInterval * 60; while (counter--) swiWaitForVBlank(); #else if (timeInterval > UINT_MAX) @throw [OFOutOfRangeException exception]; sleep((unsigned int)timeInterval); usleep((unsigned int) ((timeInterval - (unsigned int)timeInterval) * 1000000)); #endif } + (void)sleepUntilDate: (OFDate *)date { [self sleepForTimeInterval: date.timeIntervalSinceNow]; } |
︙ | ︙ | |||
311 312 313 314 315 316 317 | * returns while being declared OF_NO_RETURN. */ OF_UNREACHABLE } + (void)terminateWithObject: (id)object { | | | | | | | | | | | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 | * returns while being declared OF_NO_RETURN. */ OF_UNREACHABLE } + (void)terminateWithObject: (id)object { OFThread *thread = OFTLSKeyGet(threadSelfKey); if (thread == mainThread) @throw [OFInvalidArgumentException exception]; OFEnsure(thread != nil); thread->_returnValue = [object retain]; longjmp(thread->_exitEnv, 1); OF_UNREACHABLE } + (void)setName: (OFString *)name { [OFThread currentThread].name = name; if (name != nil) OFSetThreadName( [name cStringWithEncoding: [OFLocale encoding]]); else OFSetThreadName(class_getName([self class])); } + (OFString *)name { return [OFThread currentThread].name; } + (void)of_createMainThread { mainThread = [[OFThread alloc] init]; mainThread->_thread = OFCurrentPlainThread(); mainThread->_running = OFThreadStateRunning; if (OFTLSKeySet(threadSelfKey, mainThread) != 0) @throw [OFInitializationFailedException exceptionWithClass: self]; } - (instancetype)init { self = [super init]; @try { if (OFPlainThreadAttributesInit(&_attr) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } @catch (id e) { [self release]; @throw e; } return self; } # ifdef OF_HAVE_BLOCKS - (instancetype)initWithThreadBlock: (OFThreadBlock)threadBlock { self = [self init]; @try { _threadBlock = [threadBlock copy]; } @catch (id e) { [self release]; |
︙ | ︙ | |||
407 408 409 410 411 412 413 | [_DNSResolver release]; _DNSResolver = nil; # endif } - (void)start { | > > | | | | | | < | > > | | | | > | | | | | | | | 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | [_DNSResolver release]; _DNSResolver = nil; # endif } - (void)start { int error; if (_running == OFThreadStateRunning) @throw [OFThreadStillRunningException exceptionWithThread: self]; if (_running == OFThreadStateWaitingForJoin) { OFPlainThreadDetach(_thread); [_returnValue release]; } [self retain]; _running = OFThreadStateRunning; if ((error = OFPlainThreadNew(&_thread, [_name cStringWithEncoding: [OFLocale encoding]], callMain, self, &_attr)) != 0) { [self release]; @throw [OFThreadStartFailedException exceptionWithThread: self errNo: error]; } } - (id)join { int error; if (_running == OFThreadStateNotRunning) @throw [OFThreadJoinFailedException exceptionWithThread: self errNo: EINVAL]; if ((error = OFPlainThreadJoin(_thread)) != 0) @throw [OFThreadJoinFailedException exceptionWithThread: self errNo: error]; _running = OFThreadStateNotRunning; return _returnValue; } - (id)copy { return [self retain]; } - (OFRunLoop *)runLoop { # if defined(OF_HAVE_ATOMIC_OPS) && !defined(__clang_analyzer__) if (_runLoop == nil) { OFRunLoop *tmp = [[OFRunLoop alloc] init]; if (!OFAtomicPointerCompareAndSwap( (void **)&_runLoop, nil, tmp)) [tmp release]; } # else @synchronized (self) { if (_runLoop == nil) _runLoop = [[OFRunLoop alloc] init]; } # endif return _runLoop; } - (float)priority { return _attr.priority; } - (void)setPriority: (float)priority { if (_running == OFThreadStateRunning) @throw [OFThreadStillRunningException exceptionWithThread: self]; _attr.priority = priority; } - (size_t)stackSize { return _attr.stackSize; } - (void)setStackSize: (size_t)stackSize { if (_running == OFThreadStateRunning) @throw [OFThreadStillRunningException exceptionWithThread: self]; _attr.stackSize = stackSize; } - (bool)supportsSockets { return _supportsSockets; } - (void)setSupportsSockets: (bool)supportsSockets { if (_running == OFThreadStateRunning) @throw [OFThreadStillRunningException exceptionWithThread: self]; _supportsSockets = supportsSockets; } - (void)dealloc { if (_running == OFThreadStateRunning) @throw [OFThreadStillRunningException exceptionWithThread: self]; /* * We should not be running anymore, but call detach in order to free * the resources. */ if (_running == OFThreadStateWaitingForJoin) OFPlainThreadDetach(_thread); [_returnValue release]; # ifdef OF_HAVE_BLOCKS [_threadBlock release]; # endif [super dealloc]; |
︙ | ︙ |
Deleted src/OFThreadPool.h version [9825eb68b1].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/OFThreadPool.m version [29bc99edba].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/OFTimer+Private.h from [3bdcab087f] to [37a8d06411].
1 | /* | < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFTimer.h" OF_ASSUME_NONNULL_BEGIN OF_DIRECT_MEMBERS @interface OFTimer () - (void)of_setInRunLoop: (nullable OFRunLoop *)runLoop mode: (nullable OFRunLoopMode)mode; @end OF_ASSUME_NONNULL_END |
Modified src/OFTimer.h from [e351b12ba6] to [bedc280158].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | #ifdef OF_HAVE_BLOCKS /** * @brief A block to execute when a timer fires. * * @param timer The timer which fired */ | | | | | | | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #ifdef OF_HAVE_BLOCKS /** * @brief A block to execute when a timer fires. * * @param timer The timer which fired */ typedef void (^OFTimerBlock)(OFTimer *timer); #endif /** * @class OFTimer OFTimer.h ObjFW/OFTimer.h * * @brief A class for creating and firing timers. */ OF_SUBCLASSING_RESTRICTED @interface OFTimer: OFObject <OFComparing> { OFDate *_fireDate; OFTimeInterval _interval; id _target; id _Nullable _object1, _object2, _object3, _object4; SEL _selector; unsigned char _arguments; bool _repeats; #ifdef OF_HAVE_BLOCKS OFTimerBlock _block; #endif bool _valid; #ifdef OF_HAVE_THREADS OFCondition *_condition; bool _done; #endif OFRunLoop *_Nullable _inRunLoop; OFRunLoopMode _Nullable _inRunLoopMode; } /** * @brief The time interval in which the timer will repeat, if it is a * repeating timer. */ @property (readonly, nonatomic) OFTimeInterval timeInterval; /** * @brief Whether the timer repeats. */ @property (readonly, nonatomic) bool repeats; /** * @brief Whether the timer is valid. */ @property (readonly, nonatomic, getter=isValid) bool valid; /** |
︙ | ︙ | |||
95 96 97 98 99 100 101 | * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ | | | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector repeats: (bool)repeats; /** * @brief Creates and schedules a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target * @param object An object to pass when calling the selector on the target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (nullable id)object repeats: (bool)repeats; /** * @brief Creates and schedules a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target * @param object1 The first object to pass when calling the selector on the * target * @param object2 The second object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 repeats: (bool)repeats; /** |
︙ | ︙ | |||
151 152 153 154 155 156 157 | * @param object2 The second object to pass when calling the selector on the * target * @param object3 The third object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | * @param object2 The second object to pass when calling the selector on the * target * @param object3 The third object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 object: (nullable id)object3 repeats: (bool)repeats; |
︙ | ︙ | |||
176 177 178 179 180 181 182 | * @param object3 The third object to pass when calling the selector on the * target * @param object4 The fourth object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ | | | | | | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | * @param object3 The third object to pass when calling the selector on the * target * @param object4 The fourth object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 object: (nullable id)object3 object: (nullable id)object4 repeats: (bool)repeats; #ifdef OF_HAVE_BLOCKS /** * @brief Creates and schedules a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param repeats Whether the timer repeats after it has been executed * @param block The block to invoke when the timer fires * @return A new, autoreleased timer */ + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval repeats: (bool)repeats block: (OFTimerBlock)block; #endif /** * @brief Creates a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector repeats: (bool)repeats; /** * @brief Creates a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target * @param object An object to pass when calling the selector on the target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (nullable id)object repeats: (bool)repeats; /** * @brief Creates a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param target The target on which to call the selector * @param selector The selector to call on the target * @param object1 The first object to pass when calling the selector on the * target * @param object2 The second object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 repeats: (bool)repeats; /** |
︙ | ︙ | |||
264 265 266 267 268 269 270 | * @param object2 The second object to pass when calling the selector on the * target * @param object3 The third object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ | | | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | * @param object2 The second object to pass when calling the selector on the * target * @param object3 The third object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 object: (nullable id)object3 repeats: (bool)repeats; |
︙ | ︙ | |||
289 290 291 292 293 294 295 | * @param object3 The third object to pass when calling the selector on the * target * @param object4 The fourth object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ | | | | | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | * @param object3 The third object to pass when calling the selector on the * target * @param object4 The fourth object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return A new, autoreleased timer */ + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 object: (nullable id)object3 object: (nullable id)object4 repeats: (bool)repeats; #ifdef OF_HAVE_BLOCKS /** * @brief Creates a new timer with the specified time interval. * * @param timeInterval The time interval after which the timer should be fired * @param repeats Whether the timer repeats after it has been executed * @param block The block to invoke when the timer fires * @return A new, autoreleased timer */ + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval repeats: (bool)repeats block: (OFTimerBlock)block; #endif - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated timer with the specified time * interval. * * @param fireDate The date at which the timer should fire * @param interval The time interval after which to repeat the timer, if it is * a repeating timer * @param target The target on which to call the selector * @param selector The selector to call on the target * @param repeats Whether the timer repeats after it has been executed * @return An initialized timer */ - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval target: (id)target selector: (SEL)selector repeats: (bool)repeats; /** * @brief Initializes an already allocated timer with the specified time * interval. * * @param fireDate The date at which the timer should fire * @param interval The time interval after which to repeat the timer, if it is * a repeating timer * @param target The target on which to call the selector * @param selector The selector to call on the target * @param object An object to pass when calling the selector on the target * @param repeats Whether the timer repeats after it has been executed * @return An initialized timer */ - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval target: (id)target selector: (SEL)selector object: (nullable id)object repeats: (bool)repeats; /** * @brief Initializes an already allocated timer with the specified time |
︙ | ︙ | |||
369 370 371 372 373 374 375 | * target * @param object2 The second object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return An initialized timer */ - (instancetype)initWithFireDate: (OFDate *)fireDate | | | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | * target * @param object2 The second object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return An initialized timer */ - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval target: (id)target selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 repeats: (bool)repeats; /** |
︙ | ︙ | |||
395 396 397 398 399 400 401 | * target * @param object3 The third object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return An initialized timer */ - (instancetype)initWithFireDate: (OFDate *)fireDate | | | 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | * target * @param object3 The third object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return An initialized timer */ - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval target: (id)target selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 object: (nullable id)object3 repeats: (bool)repeats; |
︙ | ︙ | |||
424 425 426 427 428 429 430 | * target * @param object4 The fourth object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return An initialized timer */ - (instancetype)initWithFireDate: (OFDate *)fireDate | | | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | * target * @param object4 The fourth object to pass when calling the selector on the * target * @param repeats Whether the timer repeats after it has been executed * @return An initialized timer */ - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval target: (id)target selector: (SEL)selector object: (nullable id)object1 object: (nullable id)object2 object: (nullable id)object3 object: (nullable id)object4 repeats: (bool)repeats; |
︙ | ︙ | |||
446 447 448 449 450 451 452 | * @param interval The time interval after which to repeat the timer, if it is * a repeating timer * @param repeats Whether the timer repeats after it has been executed * @param block The block to invoke when the timer fires * @return An initialized timer */ - (instancetype)initWithFireDate: (OFDate *)fireDate | | | > > > > > > > > | 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | * @param interval The time interval after which to repeat the timer, if it is * a repeating timer * @param repeats Whether the timer repeats after it has been executed * @param block The block to invoke when the timer fires * @return An initialized timer */ - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval repeats: (bool)repeats block: (OFTimerBlock)block; #endif /** * @brief Compares the timer to another timer. * * @param timer The timer to compare the string to * @return The result of the comparison */ - (OFComparisonResult)compare: (OFTimer *)timer; /** * @brief Fires the timer, meaning it will execute the specified selector on the * target. */ - (void)fire; /** |
︙ | ︙ |
Modified src/OFTimer.m from [b1d045935e] to [a9abf62d66].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | #ifdef OF_HAVE_THREADS # import "OFCondition.h" #endif #import "OFInvalidArgumentException.h" @implementation OFTimer | | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | #ifdef OF_HAVE_THREADS # import "OFCondition.h" #endif #import "OFInvalidArgumentException.h" @implementation OFTimer @synthesize timeInterval = _interval, repeats = _repeats, valid = _valid; + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector repeats: (bool)repeats { void *pool = objc_autoreleasePoolPush(); OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval]; id timer = [[[self alloc] initWithFireDate: fireDate interval: timeInterval target: target selector: selector repeats: repeats] autorelease]; [[OFRunLoop currentRunLoop] addTimer: timer]; [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (id)object repeats: (bool)repeats { void *pool = objc_autoreleasePoolPush(); OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval]; |
︙ | ︙ | |||
75 76 77 78 79 80 81 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (id)object1 object: (id)object2 repeats: (bool)repeats { void *pool = objc_autoreleasePoolPush(); |
︙ | ︙ | |||
100 101 102 103 104 105 106 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } | | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (id)object1 object: (id)object2 object: (id)object3 repeats: (bool)repeats { |
︙ | ︙ | |||
127 128 129 130 131 132 133 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (id)object1 object: (id)object2 object: (id)object3 object: (id)object4 repeats: (bool)repeats |
︙ | ︙ | |||
157 158 159 160 161 162 163 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } #ifdef OF_HAVE_BLOCKS | | | | | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } #ifdef OF_HAVE_BLOCKS + (instancetype)scheduledTimerWithTimeInterval: (OFTimeInterval)timeInterval repeats: (bool)repeats block: (OFTimerBlock)block { void *pool = objc_autoreleasePoolPush(); OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval]; id timer = [[[self alloc] initWithFireDate: fireDate interval: timeInterval repeats: repeats block: block] autorelease]; [[OFRunLoop currentRunLoop] addTimer: timer]; [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } #endif + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector repeats: (bool)repeats { void *pool = objc_autoreleasePoolPush(); OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval]; id timer = [[[self alloc] initWithFireDate: fireDate interval: timeInterval target: target selector: selector repeats: repeats] autorelease]; [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (id)object repeats: (bool)repeats { void *pool = objc_autoreleasePoolPush(); OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval]; id timer = [[[self alloc] initWithFireDate: fireDate interval: timeInterval target: target selector: selector object: object repeats: repeats] autorelease]; [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (id)object1 object: (id)object2 repeats: (bool)repeats { void *pool = objc_autoreleasePoolPush(); |
︙ | ︙ | |||
240 241 242 243 244 245 246 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } | | | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (id)object1 object: (id)object2 object: (id)object3 repeats: (bool)repeats { |
︙ | ︙ | |||
265 266 267 268 269 270 271 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } | | | 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval target: (id)target selector: (SEL)selector object: (id)object1 object: (id)object2 object: (id)object3 object: (id)object4 repeats: (bool)repeats |
︙ | ︙ | |||
293 294 295 296 297 298 299 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } #ifdef OF_HAVE_BLOCKS | | | | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | [timer retain]; objc_autoreleasePoolPop(pool); return [timer autorelease]; } #ifdef OF_HAVE_BLOCKS + (instancetype)timerWithTimeInterval: (OFTimeInterval)timeInterval repeats: (bool)repeats block: (OFTimerBlock)block { void *pool = objc_autoreleasePoolPush(); OFDate *fireDate = [OFDate dateWithTimeIntervalSinceNow: timeInterval]; id timer = [[[self alloc] initWithFireDate: fireDate interval: timeInterval repeats: repeats block: block] autorelease]; |
︙ | ︙ | |||
317 318 319 320 321 322 323 | - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)of_initWithFireDate: (OFDate *)fireDate | | | 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)of_initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval target: (id)target selector: (SEL)selector object: (id)object1 object: (id)object2 object: (id)object3 object: (id)object4 arguments: (unsigned char)arguments |
︙ | ︙ | |||
354 355 356 357 358 359 360 | @throw e; } return self; } - (instancetype)initWithFireDate: (OFDate *)fireDate | | | | | | | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | @throw e; } return self; } - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval target: (id)target selector: (SEL)selector repeats: (bool)repeats { return [self of_initWithFireDate: fireDate interval: interval target: target selector: selector object: nil object: nil object: nil object: nil arguments: 0 repeats: repeats]; } - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval target: (id)target selector: (SEL)selector object: (id)object repeats: (bool)repeats { return [self of_initWithFireDate: fireDate interval: interval target: target selector: selector object: object object: nil object: nil object: nil arguments: 1 repeats: repeats]; } - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval target: (id)target selector: (SEL)selector object: (id)object1 object: (id)object2 repeats: (bool)repeats { return [self of_initWithFireDate: fireDate interval: interval target: target selector: selector object: object1 object: object2 object: nil object: nil arguments: 2 repeats: repeats]; } - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval target: (id)target selector: (SEL)selector object: (id)object1 object: (id)object2 object: (id)object3 repeats: (bool)repeats { return [self of_initWithFireDate: fireDate interval: interval target: target selector: selector object: object1 object: object2 object: object3 object: nil arguments: 3 repeats: repeats]; } - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval target: (id)target selector: (SEL)selector object: (id)object1 object: (id)object2 object: (id)object3 object: (id)object4 repeats: (bool)repeats |
︙ | ︙ | |||
455 456 457 458 459 460 461 | object: object4 arguments: 4 repeats: repeats]; } #ifdef OF_HAVE_BLOCKS - (instancetype)initWithFireDate: (OFDate *)fireDate | | | | 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | object: object4 arguments: 4 repeats: repeats]; } #ifdef OF_HAVE_BLOCKS - (instancetype)initWithFireDate: (OFDate *)fireDate interval: (OFTimeInterval)interval repeats: (bool)repeats block: (OFTimerBlock)block { self = [super init]; @try { _fireDate = [fireDate retain]; _interval = interval; _repeats = repeats; |
︙ | ︙ | |||
504 505 506 507 508 509 510 | #ifdef OF_HAVE_THREADS [_condition release]; #endif [super dealloc]; } | < < | | | < < | < | | | | < | < | 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 | #ifdef OF_HAVE_THREADS [_condition release]; #endif [super dealloc]; } - (OFComparisonResult)compare: (OFTimer *)timer { if (![timer isKindOfClass: [OFTimer class]]) @throw [OFInvalidArgumentException exception]; return [_fireDate compare: timer->_fireDate]; } - (void)of_setInRunLoop: (OFRunLoop *)runLoop mode: (OFRunLoopMode)mode { OFRunLoop *oldInRunLoop = _inRunLoop; OFRunLoopMode oldInRunLoopMode = _inRunLoopMode; _inRunLoop = [runLoop retain]; [oldInRunLoop release]; _inRunLoopMode = [mode copy]; [oldInRunLoopMode release]; } - (void)fire { void *pool = objc_autoreleasePoolPush(); id target = [[_target retain] autorelease]; id object1 = [[_object1 retain] autorelease]; id object2 = [[_object2 retain] autorelease]; id object3 = [[_object3 retain] autorelease]; id object4 = [[_object4 retain] autorelease]; OFEnsure(_arguments <= 4); if (_repeats && _valid) { int64_t missedIntervals = -_fireDate.timeIntervalSinceNow / _interval; OFTimeInterval newFireDate; OFRunLoop *runLoop; /* In case the clock was changed backwards */ if (missedIntervals < 0) missedIntervals = 0; newFireDate = _fireDate.timeIntervalSince1970 + (missedIntervals + 1) * _interval; [_fireDate release]; _fireDate = [[OFDate alloc] initWithTimeIntervalSince1970: newFireDate]; runLoop = [OFRunLoop currentRunLoop]; [runLoop addTimer: self forMode: runLoop.currentMode]; } else [self invalidate]; #ifdef OF_HAVE_BLOCKS if (_block != NULL) _block(self); else { #endif switch (_arguments) { case 0: [target performSelector: _selector]; break; case 1: [target performSelector: _selector withObject: object1]; break; case 2: [target performSelector: _selector withObject: object1 withObject: object2]; break; case 3: |
︙ | ︙ | |||
631 632 633 634 635 636 637 | [_inRunLoop of_removeTimer: self forMode: _inRunLoopMode]; old = _fireDate; _fireDate = [fireDate copy]; [old release]; | | < | 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | [_inRunLoop of_removeTimer: self forMode: _inRunLoopMode]; old = _fireDate; _fireDate = [fireDate copy]; [old release]; [_inRunLoop addTimer: self forMode: _inRunLoopMode]; } } @finally { [self release]; } } - (void)invalidate |
︙ | ︙ | |||
672 673 674 675 676 677 678 679 | [_condition wait]; } @finally { [_condition unlock]; } } #endif @end | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | [_condition wait]; } @finally { [_condition unlock]; } } #endif - (OFString *)description { #ifdef OF_HAVE_BLOCKS if (_block != NULL) return [OFString stringWithFormat: @"<%@:\n" @"\tFire date: %@\n" @"\tInterval: %lf\n" @"\tRepeats: %s\n" @"\tBlock: %@\n" @"\tValid: %s\n" @">", self.class, _fireDate, _interval, (_repeats ? "yes" : "no"), _block, (_valid ? "yes" : "no")]; else #endif return [OFString stringWithFormat: @"<%@:\n" @"\tFire date: %@\n" @"\tInterval: %lf\n" @"\tRepeats: %s\n" @"\tTarget: %@\n" @"\tSelector: %s\n" @"\tValid: %s\n" @">", self.class, _fireDate, _interval, (_repeats ? "yes" : "no"), _target, sel_getName(_selector), (_valid ? "yes" : "no")]; } @end |
Modified src/OFTriple.h from [cbb4c88048] to [190f8c3dbc].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFTriple.m from [9a522e8d33] to [51ba3c68c4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
97 98 99 100 101 102 103 | return false; return true; } - (unsigned long)hash { | | | | | | | | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, [_firstObject hash]); OFHashAddHash(&hash, [_secondObject hash]); OFHashAddHash(&hash, [_thirdObject hash]); OFHashFinalize(&hash); return hash; } - (id)copy { return [self retain]; |
︙ | ︙ |
Modified src/OFUDPSocket+Private.h from [bc60d66b62] to [4a674f5731].
1 | /* | < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFUDPSocket.h" OF_ASSUME_NONNULL_BEGIN OF_DIRECT_MEMBERS @interface OFUDPSocket () - (uint16_t)of_bindToAddress: (OFSocketAddress *)address extraType: (int)extraType; @end OF_ASSUME_NONNULL_END |
Modified src/OFUDPSocket.h from [58fc97b11e] to [3a21c440bc].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | @end /** * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h * * @brief A class which provides methods to create and use UDP sockets. * | | | | > | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | @end /** * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h * * @brief A class which provides methods to create and use UDP sockets. * * Addresses are of type @ref OFSocketAddress. You can use the current thread's * @ref OFDNSResolver to create an address for a host / port pair, * @ref OFSocketAddressString to get the IP address string for an address and * @ref OFSocketAddressPort to get the port for an address. If you want to * compare two addresses, you can use * @ref OFSocketAddressEqual and you can use @ref OFSocketAddressHash to get a * hash to use in e.g. @ref OFMapTable. * * @warning Even though the OFCopying protocol is implemented, it does *not* * return an independent copy of the socket, but instead retains it. * This is so that the socket can be used as a key for a dictionary, * so context can be associated with a socket. Using a socket in more * than one thread at the same time is not thread-safe, even if copy |
︙ | ︙ | |||
70 71 72 73 74 75 76 | * * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for * IPv6 to bind to all. * @param port The port to bind to. If the port is 0, an unused port will be * chosen, which can be obtained using the return value. * @return The port the socket was bound to */ | | < | 69 70 71 72 73 74 75 76 77 78 79 | * * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for * IPv6 to bind to all. * @param port The port to bind to. If the port is 0, an unused port will be * chosen, which can be obtained using the return value. * @return The port the socket was bound to */ - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port; @end OF_ASSUME_NONNULL_END |
Modified src/OFUDPSocket.m from [8b135fcca2] to [b89b6c4724].
1 | /* | < < | > > > > > > > < < < | < | < | | | < | | | | < | > | | | | | | < | < | | > > | < < | | | | | < | > | | | | | | < | > | | | | < | > | | | | < | | | | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #ifndef _XOPEN_SOURCE_EXTENDED # define _XOPEN_SOURCE_EXTENDED #endif #define _HPUX_ALT_XOPEN_SOCKET_API #include <errno.h> #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFUDPSocket.h" #import "OFUDPSocket+Private.h" #import "OFDNSResolver.h" #import "OFData.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFThread.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" @implementation OFUDPSocket @dynamic delegate; - (uint16_t)of_bindToAddress: (OFSocketAddress *)address extraType: (int)extraType OF_DIRECT { void *pool = objc_autoreleasePoolPush(); uint16_t port; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; #endif if ((_socket = socket(address->sockaddr.sockaddr.sa_family, SOCK_DGRAM | SOCK_CLOEXEC | extraType, 0)) == OFInvalidSocketHandle) @throw [OFBindFailedException exceptionWithHost: OFSocketAddressString(address) port: OFSocketAddressPort(address) socket: self errNo: OFSocketErrNo()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) /* {} needed to avoid warning with Clang 10 if next #if is false. */ if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) { fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); } #endif #if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS) if (OFSocketAddressPort(address) != 0) { #endif if (bind(_socket, &address->sockaddr.sockaddr, address->length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithHost: OFSocketAddressString(address) port: OFSocketAddressPort(address) socket: self errNo: errNo]; } #if defined(OF_HPUX) || defined(OF_WII) || defined(OF_NINTENDO_3DS) } else { for (;;) { uint16_t rnd = 0; int ret; while (rnd < 1024) rnd = (uint16_t)rand(); OFSocketAddressSetPort(address, rnd); if ((ret = bind(_socket, &address->sockaddr.sockaddr, address->length)) == 0) break; if (OFSocketErrNo() != EADDRINUSE) { int errNo = OFSocketErrNo(); OFString *host = OFSocketAddressString(address); port = OFSocketAddressPort(address); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithHost: host port: port socket: self errNo: errNo]; } } } #endif objc_autoreleasePoolPop(pool); if ((port = OFSocketAddressPort(address)) > 0) return port; #if !defined(OF_HPUX) && !defined(OF_WII) && !defined(OF_NINTENDO_3DS) memset(address, 0, sizeof(*address)); address->length = (socklen_t)sizeof(address->sockaddr); if (OFGetSockName(_socket, &address->sockaddr.sockaddr, &address->length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithHost: OFSocketAddressString(address) port: OFSocketAddressPort(address) socket: self errNo: errNo]; } if (address->sockaddr.sockaddr.sa_family == AF_INET) return OFFromBigEndian16(address->sockaddr.in.sin_port); # ifdef OF_HAVE_IPV6 else if (address->sockaddr.sockaddr.sa_family == AF_INET6) return OFFromBigEndian16(address->sockaddr.in6.sin6_port); # endif else { closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithHost: OFSocketAddressString(address) port: OFSocketAddressPort(address) socket: self errNo: EAFNOSUPPORT]; } #else closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithHost: OFSocketAddressString(address) port: OFSocketAddressPort(address) socket: self errNo: EADDRNOTAVAIL]; #endif } - (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port { void *pool = objc_autoreleasePoolPush(); OFData *socketAddresses; OFSocketAddress address; if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; socketAddresses = [[OFThread DNSResolver] resolveAddressesForHost: host addressFamily: OFSocketAddressFamilyAny]; address = *(OFSocketAddress *)[socketAddresses itemAtIndex: 0]; OFSocketAddressSetPort(&address, port); port = [self of_bindToAddress: &address extraType: 0]; objc_autoreleasePoolPop(pool); return port; } @end |
Added src/OFUNIXDatagramSocket.h version [15597b10d9].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFDatagramSocket.h" OF_ASSUME_NONNULL_BEGIN @class OFString; /** * @protocol OFUNIXDatagramSocketDelegate OFUNIXDatagramSocket.h \ * ObjFW/OFUNIXDatagramSocket.h * * @brief A delegate for OFUNIXDatagramSocket. */ @protocol OFUNIXDatagramSocketDelegate <OFDatagramSocketDelegate> @end /** * @class OFUNIXDatagramSocket OFUNIXDatagramSocket.h \ * ObjFW/OFUNIXDatagramSocket.h * * @brief A class which provides methods to create and use UNIX datagram * sockets. * * Addresses are of type @ref OFSocketAddress. You can use * @ref OFSocketAddressMakeUNIX to create an address or * @ref OFSocketAddressUNIXPath to get the socket path. * * @warning Even though the OFCopying protocol is implemented, it does *not* * return an independent copy of the socket, but instead retains it. * This is so that the socket can be used as a key for a dictionary, * so context can be associated with a socket. Using a socket in more * than one thread at the same time is not thread-safe, even if copy * was called to create one "instance" for every thread! */ @interface OFUNIXDatagramSocket: OFDatagramSocket { OF_RESERVE_IVARS(OFUNIXDatagramSocket, 4) } /** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id <OFUNIXDatagramSocketDelegate> delegate; /** * @brief Bind the socket to the specified path. * * @param path The path to bind to * @return The address on which this socket can be reached */ - (OFSocketAddress)bindToPath: (OFString *)path; @end OF_ASSUME_NONNULL_END |
Added src/OFUNIXDatagramSocket.m version [0b41257c02].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFUNIXDatagramSocket.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFString.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" @implementation OFUNIXDatagramSocket @dynamic delegate; - (OFSocketAddress)bindToPath: (OFString *)path { OFSocketAddress address; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; address = OFSocketAddressMakeUNIX(path); if ((_socket = socket(address.sockaddr.sockaddr.sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0)) == OFInvalidSocketHandle) @throw [OFBindFailedException exceptionWithPath: path socket: self errNo: OFSocketErrNo()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithPath: path socket: self errNo: errNo]; } return address; } @end |
Added src/OFUNIXStreamSocket.h version [34276ad0c9].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFStreamSocket.h" OF_ASSUME_NONNULL_BEGIN @class OFString; /** * @protocol OFUNIXStreamSocketDelegate OFUNIXStreamSocket.h \ * ObjFW/OFUNIXStreamSocket.h * * A delegate for OFUNIXStreamSocket. */ @protocol OFUNIXStreamSocketDelegate <OFStreamSocketDelegate> @end /** * @class OFUNIXStreamSocket OFUNIXStreamSocket.h ObjFW/OFUNIXStreamSocket.h * * @brief A class which provides methods to create and use UNIX stream sockets. * * To connect to a server, create a socket and connect it. * To create a server, create a socket, bind it and listen on it. */ @interface OFUNIXStreamSocket: OFStreamSocket { OF_RESERVE_IVARS(OFUNIXStreamSocket, 4) } /** * @brief The delegate for asynchronous operations on the socket. * * @note The delegate is retained for as long as asynchronous operations are * still ongoing. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id <OFUNIXStreamSocketDelegate> delegate; /** * @brief Connects the OFUNIXStreamSocket to the specified destination. * * @param path The path to connect to */ - (void)connectToPath: (OFString *)path; /** * @brief Binds the socket to the specified host and port. * * @param path The path to bind to */ - (void)bindToPath: (OFString *)path; @end OF_ASSUME_NONNULL_END |
Added src/OFUNIXStreamSocket.m version [72303f60dd].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #ifdef HAVE_FCNTL_H # include <fcntl.h> #endif #import "OFUNIXStreamSocket.h" #import "OFSocket.h" #import "OFSocket+Private.h" #import "OFString.h" #import "OFAlreadyConnectedException.h" #import "OFBindFailedException.h" #import "OFConnectionFailedException.h" @implementation OFUNIXStreamSocket @dynamic delegate; - (void)connectToPath: (OFString *)path { OFSocketAddress address; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; address = OFSocketAddressMakeUNIX(path); if ((_socket = socket(address.sockaddr.sockaddr.sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)) == OFInvalidSocketHandle) @throw [OFConnectionFailedException exceptionWithPath: path socket: self errNo: OFSocketErrNo()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif if (connect(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFConnectionFailedException exceptionWithPath: path socket: self errNo: errNo]; } } - (void)bindToPath: (OFString *)path { OFSocketAddress address; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) int flags; #endif if (_socket != OFInvalidSocketHandle) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; address = OFSocketAddressMakeUNIX(path); if ((_socket = socket(address.sockaddr.sockaddr.sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)) == OFInvalidSocketHandle) @throw [OFBindFailedException exceptionWithPath: path socket: self errNo: OFSocketErrNo()]; _canBlock = true; #if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); #endif if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { int errNo = OFSocketErrNo(); closesocket(_socket); _socket = OFInvalidSocketHandle; @throw [OFBindFailedException exceptionWithPath: path socket: self errNo: errNo]; } } @end |
Modified src/OFURL.h from [125797e09d] to [40faae77ac].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
131 132 133 134 135 136 137 | /** * @brief The query part of the URL as a dictionary. * * For example, a query like `key1=value1&key2=value2` would correspond to the * following dictionary: * * @{ | | | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | /** * @brief The query part of the URL as a dictionary. * * For example, a query like `key1=value1&key2=value2` would correspond to the * following dictionary: * * @{ * @"key1": @"value1", * @"key2": @"value2" * } */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFDictionary OF_GENERIC(OFString *, OFString *) *queryDictionary; /** * @brief The fragment part of the URL. |
︙ | ︙ | |||
155 156 157 158 159 160 161 | /** * @brief The URL as a string. */ @property (readonly, nonatomic) OFString *string; /** | | | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | /** * @brief The URL as a string. */ @property (readonly, nonatomic) OFString *string; /** * @brief The URL with relative subpaths resolved. */ @property (readonly, nonatomic) OFURL *URLByStandardizingPath; #ifdef OF_HAVE_FILES /** * @brief The local file system representation for a file URL. * |
︙ | ︙ | |||
187 188 189 190 191 192 193 | * @brief Creates a new URL with the specified string relative to the * specified URL. * * @param string A string describing a URL * @param URL An URL to which the string is relative * @return A new, autoreleased OFURL */ | | < | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | * @brief Creates a new URL with the specified string relative to the * specified URL. * * @param string A string describing a URL * @param URL An URL to which the string is relative * @return A new, autoreleased OFURL */ + (instancetype)URLWithString: (OFString *)string relativeToURL: (OFURL *)URL; #ifdef OF_HAVE_FILES /** * @brief Creates a new URL with the specified local file path. * * If a directory exists at the specified path, a slash is appended if there is * no slash yet. |
︙ | ︙ | |||
230 231 232 233 234 235 236 | * @brief Initializes an already allocated OFURL with the specified string and * relative URL. * * @param string A string describing a URL * @param URL A URL to which the string is relative * @return An initialized OFURL */ | | < | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | * @brief Initializes an already allocated OFURL with the specified string and * relative URL. * * @param string A string describing a URL * @param URL A URL to which the string is relative * @return An initialized OFURL */ - (instancetype)initWithString: (OFString *)string relativeToURL: (OFURL *)URL; #ifdef OF_HAVE_FILES /** * @brief Initializes an already allocated OFURL with the specified local file * path. * * If a directory exists at the specified path, a slash is appended if there is |
︙ | ︙ | |||
367 368 369 370 371 372 373 | */ + (OFCharacterSet *)URLFragmentAllowedCharacterSet; @end #ifdef __cplusplus extern "C" { #endif | | > | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | */ + (OFCharacterSet *)URLFragmentAllowedCharacterSet; @end #ifdef __cplusplus extern "C" { #endif extern bool OFURLIsIPv6Host(OFString *host); extern void OFURLVerifyIsEscaped(OFString *, OFCharacterSet *); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END #import "OFMutableURL.h" |
Modified src/OFURL.m from [a1fb3bc27c] to [8192f78e14].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | #include <stdlib.h> #include <string.h> #import "OFURL.h" #import "OFArray.h" #import "OFDictionary.h" | < < < < > > > > < < | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include <stdlib.h> #include <string.h> #import "OFURL.h" #import "OFArray.h" #import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFileManager.h" # import "OFFileURLHandler.h" #endif #import "OFNumber.h" #import "OFOnce.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" @interface OFURLAllowedCharacterSetBase: OFCharacterSet @end @interface OFURLAllowedCharacterSet: OFURLAllowedCharacterSetBase @end @interface OFURLSchemeAllowedCharacterSet: OFURLAllowedCharacterSetBase |
︙ | ︙ | |||
58 59 60 61 62 63 64 | static OFCharacterSet *URLAllowedCharacterSet = nil; static OFCharacterSet *URLSchemeAllowedCharacterSet = nil; static OFCharacterSet *URLPathAllowedCharacterSet = nil; static OFCharacterSet *URLQueryOrFragmentAllowedCharacterSet = nil; static OFCharacterSet *URLQueryKeyValueAllowedCharacterSet = nil; | | | > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | static OFCharacterSet *URLAllowedCharacterSet = nil; static OFCharacterSet *URLSchemeAllowedCharacterSet = nil; static OFCharacterSet *URLPathAllowedCharacterSet = nil; static OFCharacterSet *URLQueryOrFragmentAllowedCharacterSet = nil; static OFCharacterSet *URLQueryKeyValueAllowedCharacterSet = nil; static OFOnceControl URLAllowedCharacterSetOnce = OFOnceControlInitValue; static OFOnceControl URLQueryOrFragmentAllowedCharacterSetOnce = OFOnceControlInitValue; static void initURLAllowedCharacterSet(void) { URLAllowedCharacterSet = [[OFURLAllowedCharacterSet alloc] init]; } |
︙ | ︙ | |||
99 100 101 102 103 104 105 | [[OFURLQueryKeyValueAllowedCharacterSet alloc] init]; } OF_DIRECT_MEMBERS @interface OFInvertedCharacterSetWithoutPercent: OFCharacterSet { OFCharacterSet *_characterSet; | | | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | [[OFURLQueryKeyValueAllowedCharacterSet alloc] init]; } OF_DIRECT_MEMBERS @interface OFInvertedCharacterSetWithoutPercent: OFCharacterSet { OFCharacterSet *_characterSet; bool (*_characterIsMember)(id, SEL, OFUnichar); } - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet; @end bool OFURLIsIPv6Host(OFString *host) { const char *UTF8String = host.UTF8String; bool hasColon = false; while (*UTF8String != '\0') { if (!OFASCIIIsDigit(*UTF8String) && *UTF8String != ':' && (*UTF8String < 'a' || *UTF8String > 'f') && (*UTF8String < 'A' || *UTF8String > 'F')) return false; if (*UTF8String == ':') hasColon = true; |
︙ | ︙ | |||
143 144 145 146 147 148 149 | - (void)release { } - (unsigned int)retainCount { | | | | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | - (void)release { } - (unsigned int)retainCount { return OFMaxRetainCount; } @end @implementation OFURLAllowedCharacterSet - (bool)characterIsMember: (OFUnichar)character { if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; switch (character) { case '-': case '.': case '_': case '~': |
︙ | ︙ | |||
177 178 179 180 181 182 183 | default: return false; } } @end @implementation OFURLSchemeAllowedCharacterSet | | | | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | default: return false; } } @end @implementation OFURLSchemeAllowedCharacterSet - (bool)characterIsMember: (OFUnichar)character { if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; switch (character) { case '+': case '-': case '.': return true; default: return false; } } @end @implementation OFURLPathAllowedCharacterSet - (bool)characterIsMember: (OFUnichar)character { if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; switch (character) { case '-': case '.': case '_': case '~': |
︙ | ︙ | |||
226 227 228 229 230 231 232 | default: return false; } } @end @implementation OFURLQueryOrFragmentAllowedCharacterSet | | | | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | default: return false; } } @end @implementation OFURLQueryOrFragmentAllowedCharacterSet - (bool)characterIsMember: (OFUnichar)character { if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; switch (character) { case '-': case '.': case '_': case '~': |
︙ | ︙ | |||
259 260 261 262 263 264 265 | default: return false; } } @end @implementation OFURLQueryKeyValueAllowedCharacterSet | | | | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | default: return false; } } @end @implementation OFURLQueryKeyValueAllowedCharacterSet - (bool)characterIsMember: (OFUnichar)character { if (character < CHAR_MAX && OFASCIIIsAlnum(character)) return true; switch (character) { case '-': case '.': case '_': case '~': |
︙ | ︙ | |||
296 297 298 299 300 301 302 | @implementation OFInvertedCharacterSetWithoutPercent - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet { self = [super init]; @try { _characterSet = [characterSet retain]; | | | | | | | | | | | | | | | | | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | @implementation OFInvertedCharacterSetWithoutPercent - (instancetype)initWithCharacterSet: (OFCharacterSet *)characterSet { self = [super init]; @try { _characterSet = [characterSet retain]; _characterIsMember = (bool (*)(id, SEL, OFUnichar)) [_characterSet methodForSelector: @selector(characterIsMember:)]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_characterSet release]; [super dealloc]; } - (bool)characterIsMember: (OFUnichar)character { return (character != '%' && !_characterIsMember(_characterSet, @selector(characterIsMember:), character)); } @end void OFURLVerifyIsEscaped(OFString *string, OFCharacterSet *characterSet) { void *pool = objc_autoreleasePoolPush(); characterSet = [[[OFInvertedCharacterSetWithoutPercent alloc] initWithCharacterSet: characterSet] autorelease]; if ([string indexOfCharacterFromSet: characterSet] != OFNotFound) @throw [OFInvalidFormatException exception]; objc_autoreleasePoolPop(pool); } @implementation OFCharacterSet (URLCharacterSets) + (OFCharacterSet *)URLSchemeAllowedCharacterSet { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, initURLSchemeAllowedCharacterSet); return URLSchemeAllowedCharacterSet; } + (OFCharacterSet *)URLHostAllowedCharacterSet { OFOnce(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); return URLAllowedCharacterSet; } + (OFCharacterSet *)URLUserAllowedCharacterSet { OFOnce(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); return URLAllowedCharacterSet; } + (OFCharacterSet *)URLPasswordAllowedCharacterSet { OFOnce(&URLAllowedCharacterSetOnce, initURLAllowedCharacterSet); return URLAllowedCharacterSet; } + (OFCharacterSet *)URLPathAllowedCharacterSet { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, initURLPathAllowedCharacterSet); return URLPathAllowedCharacterSet; } + (OFCharacterSet *)URLQueryAllowedCharacterSet { OFOnce(&URLQueryOrFragmentAllowedCharacterSetOnce, initURLQueryOrFragmentAllowedCharacterSet); return URLQueryOrFragmentAllowedCharacterSet; } + (OFCharacterSet *)URLQueryKeyValueAllowedCharacterSet { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, initURLQueryKeyValueAllowedCharacterSet); return URLQueryKeyValueAllowedCharacterSet; } + (OFCharacterSet *)URLFragmentAllowedCharacterSet { OFOnce(&URLQueryOrFragmentAllowedCharacterSetOnce, initURLQueryOrFragmentAllowedCharacterSet); return URLQueryOrFragmentAllowedCharacterSet; } @end @implementation OFURL |
︙ | ︙ | |||
441 442 443 444 445 446 447 | self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); char *tmp, *tmp2; bool isIPv6Host = false; | < < < < < | | | | 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 | self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); char *tmp, *tmp2; bool isIPv6Host = false; UTF8String = UTF8String2 = OFStrDup(string.UTF8String); if ((tmp = strchr(UTF8String, ':')) == NULL) @throw [OFInvalidFormatException exception]; if (strncmp(tmp, "://", 3) != 0) @throw [OFInvalidFormatException exception]; for (tmp2 = UTF8String; tmp2 < tmp; tmp2++) *tmp2 = OFASCIIToLower(*tmp2); _URLEncodedScheme = [[OFString alloc] initWithUTF8String: UTF8String length: tmp - UTF8String]; OFURLVerifyIsEscaped(_URLEncodedScheme, [OFCharacterSet URLSchemeAllowedCharacterSet]); UTF8String = tmp + 3; if ((tmp = strchr(UTF8String, '/')) != NULL) { *tmp = '\0'; tmp++; |
︙ | ︙ | |||
486 487 488 489 490 491 492 | tmp3++; _URLEncodedUser = [[OFString alloc] initWithUTF8String: UTF8String]; _URLEncodedPassword = [[OFString alloc] initWithUTF8String: tmp3]; | | | | | | 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 | tmp3++; _URLEncodedUser = [[OFString alloc] initWithUTF8String: UTF8String]; _URLEncodedPassword = [[OFString alloc] initWithUTF8String: tmp3]; OFURLVerifyIsEscaped(_URLEncodedPassword, [OFCharacterSet URLPasswordAllowedCharacterSet]); } else _URLEncodedUser = [[OFString alloc] initWithUTF8String: UTF8String]; OFURLVerifyIsEscaped(_URLEncodedUser, [OFCharacterSet URLUserAllowedCharacterSet]); UTF8String = tmp2; } if (UTF8String[0] == '[') { tmp2 = UTF8String++; while (OFASCIIIsDigit(*UTF8String) || *UTF8String == ':' || (*UTF8String >= 'a' && *UTF8String <= 'f') || (*UTF8String >= 'A' && *UTF8String <= 'F')) UTF8String++; if (*UTF8String != ']') @throw [OFInvalidFormatException exception]; UTF8String++; _URLEncodedHost = [[OFString alloc] initWithUTF8String: tmp2 length: UTF8String - tmp2]; if (*UTF8String == ':') { OFString *portString; tmp2 = ++UTF8String; while (*UTF8String != '\0') { if (!OFASCIIIsDigit(*UTF8String)) @throw [OFInvalidFormatException exception]; UTF8String++; } portString = [OFString |
︙ | ︙ | |||
566 567 568 569 570 571 572 | _port = [[OFNumber alloc] initWithUnsignedShort: portString.unsignedLongLongValue]; } else _URLEncodedHost = [[OFString alloc] initWithUTF8String: UTF8String]; if (!isIPv6Host) | | | | > > > > > > > > > > > > > > > > > | | | < < < < < < | | | | | | | | < < | < | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 | _port = [[OFNumber alloc] initWithUnsignedShort: portString.unsignedLongLongValue]; } else _URLEncodedHost = [[OFString alloc] initWithUTF8String: UTF8String]; if (!isIPv6Host) OFURLVerifyIsEscaped(_URLEncodedHost, [OFCharacterSet URLHostAllowedCharacterSet]); if ((UTF8String = tmp) != NULL) { if ((tmp = strchr(UTF8String, '#')) != NULL) { *tmp = '\0'; _URLEncodedFragment = [[OFString alloc] initWithUTF8String: tmp + 1]; OFURLVerifyIsEscaped(_URLEncodedFragment, [OFCharacterSet URLFragmentAllowedCharacterSet]); } if ((tmp = strchr(UTF8String, '?')) != NULL) { *tmp = '\0'; _URLEncodedQuery = [[OFString alloc] initWithUTF8String: tmp + 1]; OFURLVerifyIsEscaped(_URLEncodedQuery, [OFCharacterSet URLQueryAllowedCharacterSet]); } /* * Some versions of GCC issue a false-positive warning * (turned error) about a string overflow. This is a * false positive because UTF8String is set to tmp * above and tmp is either NULL or points *after* the * slash for the path. So all we do here is go back to * that slash and restore it. */ #if OF_GCC_VERSION >= 402 # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wpragmas" # pragma GCC diagnostic ignored "-Wunknown-warning-option" # pragma GCC diagnostic ignored "-Wstringop-overflow" #endif UTF8String--; *UTF8String = '/'; #if OF_GCC_VERSION >= 402 # pragma GCC diagnostic pop #endif _URLEncodedPath = [[OFString alloc] initWithUTF8String: UTF8String]; OFURLVerifyIsEscaped(_URLEncodedPath, [OFCharacterSet URLPathAllowedCharacterSet]); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } @finally { OFFreeMemory(UTF8String2); } return self; } - (instancetype)initWithString: (OFString *)string relativeToURL: (OFURL *)URL { char *UTF8String, *UTF8String2 = NULL; if ([string containsString: @"://"]) return [self initWithString: string]; self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); char *tmp; _URLEncodedScheme = [URL->_URLEncodedScheme copy]; _URLEncodedHost = [URL->_URLEncodedHost copy]; _port = [URL->_port copy]; _URLEncodedUser = [URL->_URLEncodedUser copy]; _URLEncodedPassword = [URL->_URLEncodedPassword copy]; UTF8String = UTF8String2 = OFStrDup(string.UTF8String); if ((tmp = strchr(UTF8String, '#')) != NULL) { *tmp = '\0'; _URLEncodedFragment = [[OFString alloc] initWithUTF8String: tmp + 1]; OFURLVerifyIsEscaped(_URLEncodedFragment, [OFCharacterSet URLFragmentAllowedCharacterSet]); } if ((tmp = strchr(UTF8String, '?')) != NULL) { *tmp = '\0'; _URLEncodedQuery = [[OFString alloc] initWithUTF8String: tmp + 1]; OFURLVerifyIsEscaped(_URLEncodedQuery, [OFCharacterSet URLQueryAllowedCharacterSet]); } if (*UTF8String == '/') _URLEncodedPath = [[OFString alloc] initWithUTF8String: UTF8String]; else { OFString *relativePath = [OFString stringWithUTF8String: UTF8String]; if ([URL->_URLEncodedPath hasSuffix: @"/"]) _URLEncodedPath = [[URL->_URLEncodedPath stringByAppendingString: relativePath] copy]; else { OFMutableString *path = [OFMutableString stringWithString: (URL->_URLEncodedPath != nil ? URL->_URLEncodedPath : @"/")]; OFRange range = [path rangeOfString: @"/" options: OFStringSearchBackwards]; if (range.location == OFNotFound) @throw [OFInvalidFormatException exception]; range.location++; range.length = path.length - range.location; [path replaceCharactersInRange: range withString: relativePath]; [path makeImmutable]; _URLEncodedPath = [path copy]; } } OFURLVerifyIsEscaped(_URLEncodedPath, [OFCharacterSet URLPathAllowedCharacterSet]); objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } @finally { OFFreeMemory(UTF8String2); } return self; } #ifdef OF_HAVE_FILES - (instancetype)initFileURLWithPath: (OFString *)path { bool isDirectory; @try { void *pool = objc_autoreleasePoolPush(); isDirectory = [path of_isDirectoryPath]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } self = [self initFileURLWithPath: path isDirectory: isDirectory]; return self; } - (instancetype)initFileURLWithPath: (OFString *)path isDirectory: (bool)isDirectory { |
︙ | ︙ | |||
777 778 779 780 781 782 783 | - (instancetype)initWithSerialization: (OFXMLElement *)element { void *pool = objc_autoreleasePoolPush(); OFString *stringValue; @try { if (![element.name isEqual: self.className] || | | | 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 | - (instancetype)initWithSerialization: (OFXMLElement *)element { void *pool = objc_autoreleasePoolPush(); OFString *stringValue; @try { if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; stringValue = element.stringValue; } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
848 849 850 851 852 853 854 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | | | | | 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _URLEncodedScheme.hash); OFHashAddHash(&hash, _URLEncodedHost.hash); OFHashAddHash(&hash, _port.hash); OFHashAddHash(&hash, _URLEncodedUser.hash); OFHashAddHash(&hash, _URLEncodedPassword.hash); OFHashAddHash(&hash, _URLEncodedPath.hash); OFHashAddHash(&hash, _URLEncodedQuery.hash); OFHashAddHash(&hash, _URLEncodedFragment.hash); OFHashFinalize(&hash); return hash; } - (OFString *)scheme { return _URLEncodedScheme.stringByURLDecoding; } - (OFString *)URLEncodedScheme { return _URLEncodedScheme; } - (OFString *)host { if ([_URLEncodedHost hasPrefix: @"["] && [_URLEncodedHost hasSuffix: @"]"]) { OFString *host = [_URLEncodedHost substringWithRange: OFRangeMake(1, _URLEncodedHost.length - 2)]; if (!OFURLIsIPv6Host(host)) @throw [OFInvalidArgumentException exception]; return host; } return _URLEncodedHost.stringByURLDecoding; } |
︙ | ︙ | |||
948 949 950 951 952 953 954 | #ifdef OF_HAVE_FILES if (isFile) { OFString *path = [_URLEncodedPath of_URLPathToPathWithURLEncodedHost: nil]; ret = [[path.pathComponents mutableCopy] autorelease]; if (![ret.firstObject isEqual: @"/"]) | | < | < | 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 | #ifdef OF_HAVE_FILES if (isFile) { OFString *path = [_URLEncodedPath of_URLPathToPathWithURLEncodedHost: nil]; ret = [[path.pathComponents mutableCopy] autorelease]; if (![ret.firstObject isEqual: @"/"]) [ret insertObject: @"/" atIndex: 0]; } else #endif ret = [[[_URLEncodedPath componentsSeparatedByString: @"/"] mutableCopy] autorelease]; count = ret.count; if (count > 0 && [ret.firstObject length] == 0) [ret replaceObjectAtIndex: 0 withObject: @"/"]; for (size_t i = 0; i < count; i++) { OFString *component = [ret objectAtIndex: i]; #ifdef OF_HAVE_FILES if (isFile) component = |
︙ | ︙ | |||
1160 1161 1162 1163 1164 1165 1166 | return [path autorelease]; } #endif - (OFURL *)URLByAppendingPathComponent: (OFString *)component { OFMutableURL *URL = [[self mutableCopy] autorelease]; | < < < | < < < < | | 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 | return [path autorelease]; } #endif - (OFURL *)URLByAppendingPathComponent: (OFString *)component { OFMutableURL *URL = [[self mutableCopy] autorelease]; [URL appendPathComponent: component]; [URL makeImmutable]; return URL; } - (OFURL *)URLByAppendingPathComponent: (OFString *)component isDirectory: (bool)isDirectory { OFMutableURL *URL = [[self mutableCopy] autorelease]; [URL appendPathComponent: component isDirectory: isDirectory]; [URL makeImmutable]; return URL; } - (OFURL *)URLByStandardizingPath { OFMutableURL *URL = [[self mutableCopy] autorelease]; [URL standardizePath]; [URL makeImmutable]; return URL; } - (OFString *)description { return [OFString stringWithFormat: @"<%@: %@>", self.class, self.string]; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS stringValue: self.string]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } @end |
Modified src/OFURLHandler.h from [95a1235a75] to [0e58f1d36b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
49 50 51 52 53 54 55 | * created per scheme. * * @param class_ The class to register as the handler for the specified scheme * @param scheme The scheme for which to register the handler * @return Whether the class was successfully registered. If a handler for the * same scheme is already registered, registration fails. */ | | < | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | * created per scheme. * * @param class_ The class to register as the handler for the specified scheme * @param scheme The scheme for which to register the handler * @return Whether the class was successfully registered. If a handler for the * same scheme is already registered, registration fails. */ + (bool)registerClass: (Class)class_ forScheme: (OFString *)scheme; /** * @brief Returns the handler for the specified URL. * * @return The handler for the specified URL. */ + (nullable OF_KINDOF(OFURLHandler *))handlerForURL: (OFURL *)URL; |
︙ | ︙ | |||
90 91 92 93 94 95 96 | * `w+x` | Read-write, create or fail, exclusive * `a` | Write-only, create or append * `a+` | Read-write, create or append * @n * The handler is allowed to not implement all modes and is also * allowed to implement additional, scheme-specific modes. */ | | < | | < | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | * `w+x` | Read-write, create or fail, exclusive * `a` | Write-only, create or append * `a+` | Read-write, create or append * @n * The handler is allowed to not implement all modes and is also * allowed to implement additional, scheme-specific modes. */ - (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode; /** * @brief Returns the attributes for the item at the specified URL. * * @param URL The URL to return the attributes for * @return A dictionary of attributes for the specified URL, with the keys of * type @ref OFFileAttributeKey */ - (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL; /** * @brief Sets the attributes for the item at the specified URL. * * All attributes not part of the dictionary are left unchanged. * * @param attributes The attributes to set for the specified URL * @param URL The URL of the item to set the attributes for */ - (void)setAttributes: (OFFileAttributes)attributes ofItemAtURL: (OFURL *)URL; /** * @brief Checks whether a file exists at the specified URL. * * @param URL The URL to check * @return A boolean whether there is a file at the specified URL */ |
︙ | ︙ | |||
137 138 139 140 141 142 143 | * @brief Creates a directory at the specified URL. * * @param URL The URL of the directory to create */ - (void)createDirectoryAtURL: (OFURL *)URL; /** | | > | | | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | * @brief Creates a directory at the specified URL. * * @param URL The URL of the directory to create */ - (void)createDirectoryAtURL: (OFURL *)URL; /** * @brief Returns an array with the URLs of the items in the specified * directory. * * @note `.` and `..` are not part of the returned array. * * @param URL The URL to the directory whose items should be returned * @return An array with the URLs of the items in the specified directory */ - (OFArray OF_GENERIC(OFURL *) *)contentsOfDirectoryAtURL: (OFURL *)URL; /** * @brief Removes the item at the specified URL. * * If the item at the specified URL is a directory, it is removed recursively. * * @param URL The URL to the item which should be removed |
︙ | ︙ | |||
166 167 168 169 170 171 172 | * name of the item. * * This method is not available for all URLs. * * @param source The URL to the item for which a link should be created * @param destination The URL to the item which should link to the source */ | | < | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | * name of the item. * * This method is not available for all URLs. * * @param source The URL to the item for which a link should be created * @param destination The URL to the item which should link to the source */ - (void)linkItemAtURL: (OFURL *)source toURL: (OFURL *)destination; /** * @brief Creates a symbolic link for an item. * * The destination uRL must have a full path, which means it must include the * name of the item. * |
︙ | ︙ | |||
203 204 205 206 207 208 209 | * * @param source The file, directory or symbolic link to copy * @param destination The destination URL * @return True if an efficient copy was performed, false if an efficient copy * was not possible. Note that errors while performing a copy are * reported via exceptions and not by returning false! */ | | < | < | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | * * @param source The file, directory or symbolic link to copy * @param destination The destination URL * @return True if an efficient copy was performed, false if an efficient copy * was not possible. Note that errors while performing a copy are * reported via exceptions and not by returning false! */ - (bool)copyItemAtURL: (OFURL *)source toURL: (OFURL *)destination; /** * @brief Tries to efficiently move an item. If a move would only be possible * by copying the source and deleting it, it returns false. * * The destination URL must have a full path, which means it must include the * name of the item. * * If the destination is on a different logical device or uses a different * scheme, an efficient move is not possible and false is returned. * * @param source The item to rename * @param destination The new name for the item * @return True if an efficient move was performed, false if an efficient move * was not possible. Note that errors while performing a move are * reported via exceptions and not by returning false! */ - (bool)moveItemAtURL: (OFURL *)source toURL: (OFURL *)destination; @end OF_ASSUME_NONNULL_END |
Modified src/OFURLHandler.m from [2d065f473d] to [0e5a95e00a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS) # import "OFHTTPURLHandler.h" #endif static OFMutableDictionary OF_GENERIC(OFString *, OFURLHandler *) *handlers; #ifdef OF_HAVE_THREADS static OFMutex *mutex; #endif @implementation OFURLHandler @synthesize scheme = _scheme; + (void)initialize { if (self != [OFURLHandler class]) return; handlers = [[OFMutableDictionary alloc] init]; #ifdef OF_HAVE_THREADS mutex = [[OFMutex alloc] init]; #endif #ifdef OF_HAVE_FILES | > > > > > > > | < | < | < | < | < | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | #if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS) # import "OFHTTPURLHandler.h" #endif static OFMutableDictionary OF_GENERIC(OFString *, OFURLHandler *) *handlers; #ifdef OF_HAVE_THREADS static OFMutex *mutex; static void releaseMutex(void) { [mutex release]; } #endif @implementation OFURLHandler @synthesize scheme = _scheme; + (void)initialize { if (self != [OFURLHandler class]) return; handlers = [[OFMutableDictionary alloc] init]; #ifdef OF_HAVE_THREADS mutex = [[OFMutex alloc] init]; atexit(releaseMutex); #endif #ifdef OF_HAVE_FILES [self registerClass: [OFFileURLHandler class] forScheme: @"file"]; #endif #if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS) [self registerClass: [OFHTTPURLHandler class] forScheme: @"http"]; [self registerClass: [OFHTTPURLHandler class] forScheme: @"https"]; #endif } + (bool)registerClass: (Class)class forScheme: (OFString *)scheme { #ifdef OF_HAVE_THREADS [mutex lock]; @try { #endif OFURLHandler *handler; if ([handlers objectForKey: scheme] != nil) return false; handler = [[class alloc] initWithScheme: scheme]; @try { [handlers setObject: handler forKey: scheme]; } @finally { [handler release]; } #ifdef OF_HAVE_THREADS } @finally { [mutex unlock]; } |
︙ | ︙ | |||
131 132 133 134 135 136 137 | - (void)dealloc { [_scheme release]; [super dealloc]; } | | < | < | | | < | < | < | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | - (void)dealloc { [_scheme release]; [super dealloc]; } - (OFStream *)openItemAtURL: (OFURL *)URL mode: (OFString *)mode { OF_UNRECOGNIZED_SELECTOR } - (OFFileAttributes)attributesOfItemAtURL: (OFURL *)URL { OF_UNRECOGNIZED_SELECTOR } - (void)setAttributes: (OFFileAttributes)attributes ofItemAtURL: (OFURL *)URL { OF_UNRECOGNIZED_SELECTOR } - (bool)fileExistsAtURL: (OFURL *)URL { OF_UNRECOGNIZED_SELECTOR } - (bool)directoryExistsAtURL: (OFURL *)URL { OF_UNRECOGNIZED_SELECTOR } - (void)createDirectoryAtURL: (OFURL *)URL { OF_UNRECOGNIZED_SELECTOR } - (OFArray OF_GENERIC(OFURL *) *)contentsOfDirectoryAtURL: (OFURL *)URL { OF_UNRECOGNIZED_SELECTOR } - (void)removeItemAtURL: (OFURL *)URL { OF_UNRECOGNIZED_SELECTOR } - (void)linkItemAtURL: (OFURL *)source toURL: (OFURL *)destination { OF_UNRECOGNIZED_SELECTOR } - (void)createSymbolicLinkAtURL: (OFURL *)destination withDestinationPath: (OFString *)source { OF_UNRECOGNIZED_SELECTOR } - (bool)copyItemAtURL: (OFURL *)source toURL: (OFURL *)destination { return false; } - (bool)moveItemAtURL: (OFURL *)source toURL: (OFURL *)destination { return false; } @end |
Modified src/OFUTF8String+Private.h from [03f2449d2e] to [a7a276ddae].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFUTF8String.h from [e49ea36f6c] to [d381d1f2a1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | /* * A pointer to the actual data. * * Since constant strings don't have `_storage`, they have to allocate * it on the first access. Strings created at runtime just set the * pointer to `&_storage`. */ | | | | | | < | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | /* * A pointer to the actual data. * * Since constant strings don't have `_storage`, they have to allocate * it on the first access. Strings created at runtime just set the * pointer to `&_storage`. */ struct OFUTF8StringIvars { char *cString; size_t cStringLength; bool isUTF8; size_t length; bool hasHash; unsigned long hash; bool freeWhenDone; } *restrict _s; struct OFUTF8StringIvars _storage; } @end #ifdef __cplusplus extern "C" { #endif extern int OFUTF8StringCheck(const char *, size_t, size_t *); extern size_t OFUTF8StringIndexToPosition(const char *, size_t, size_t); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFUTF8String.m from [d8b3a6972a] to [0c9d61efea].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #ifdef OF_HAVE_SYS_TYPES_H # include <sys/types.h> #endif #import "OFUTF8String.h" #import "OFUTF8String+Private.h" #import "OFArray.h" #import "OFMutableUTF8String.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" | > > < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | #ifdef OF_HAVE_SYS_TYPES_H # include <sys/types.h> #endif #import "OFUTF8String.h" #import "OFUTF8String+Private.h" #import "OFASPrintF.h" #import "OFArray.h" #import "OFData.h" #import "OFMutableUTF8String.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "unicode.h" extern const OFChar16 OFISO8859_2Table[]; extern const size_t OFISO8859_2TableOffset; extern const OFChar16 OFISO8859_3Table[]; extern const size_t OFISO8859_3TableOffset; extern const OFChar16 OFISO8859_15Table[]; extern const size_t OFISO8859_15TableOffset; extern const OFChar16 OFWindows1251Table[]; extern const size_t OFWindows1251TableOffset; extern const OFChar16 OFWindows1252Table[]; extern const size_t OFWindows1252TableOffset; extern const OFChar16 OFCodepage437Table[]; extern const size_t OFCodepage437TableOffset; extern const OFChar16 OFCodepage850Table[]; extern const size_t OFCodepage850TableOffset; extern const OFChar16 OFCodepage858Table[]; extern const size_t OFCodepage858TableOffset; extern const OFChar16 OFMacRomanTable[]; extern const size_t OFMacRomanTableOffset; extern const OFChar16 OFKOI8RTable[]; extern const size_t OFKOI8RTableOffset; extern const OFChar16 OFKOI8UTable[]; extern const size_t OFKOI8UTableOffset; static inline int memcasecmp(const char *first, const char *second, size_t length) { for (size_t i = 0; i < length; i++) { unsigned char f = first[i]; unsigned char s = second[i]; f = OFASCIIToUpper(f); s = OFASCIIToUpper(s); if (f > s) return OFOrderedDescending; if (f < s) return OFOrderedAscending; } return OFOrderedSame; } int OFUTF8StringCheck(const char *UTF8String, size_t UTF8Length, size_t *length) { size_t tmpLength = UTF8Length; int isUTF8 = 0; for (size_t i = 0; i < UTF8Length; i++) { /* No sign of UTF-8 here */ if OF_LIKELY (!(UTF8String[i] & 0x80)) |
︙ | ︙ | |||
146 147 148 149 150 151 152 | if (length != NULL) *length = tmpLength; return isUTF8; } size_t | | | | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | if (length != NULL) *length = tmpLength; return isUTF8; } size_t positionToIndex(const char *string, size_t position) { size_t idx = position; for (size_t i = 0; i < position; i++) if OF_UNLIKELY ((string[i] & 0xC0) == 0x80) idx--; return idx; } size_t OFUTF8StringIndexToPosition(const char *string, size_t idx, size_t length) { for (size_t i = 0; i <= idx; i++) if OF_UNLIKELY ((string[i] & 0xC0) == 0x80) if (++idx > length) @throw [OFInvalidFormatException exception]; return idx; } @implementation OFUTF8String - (instancetype)init { self = [super init]; @try { _s = &_storage; _s->cString = OFAllocZeroedMemory(1, 1); _s->freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
204 205 206 207 208 209 210 | } _s = &_storage; _s->cString = storage; _s->cStringLength = UTF8StringLength; | | | | | | > | | | | | | | < | | | | | | | | | | | | | | | | | | | | < | | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | } _s = &_storage; _s->cString = storage; _s->cStringLength = UTF8StringLength; switch (OFUTF8StringCheck(UTF8String, UTF8StringLength, &_s->length)) { case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } memcpy(_s->cString, UTF8String, UTF8StringLength); _s->cString[UTF8StringLength] = 0; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)cStringLength { self = [super init]; @try { const OFChar16 *table; size_t tableOffset, j; if (encoding == OFStringEncodingUTF8 && cStringLength >= 3 && memcmp(cString, "\xEF\xBB\xBF", 3) == 0) { cString += 3; cStringLength -= 3; } _s = &_storage; _s->cString = OFAllocMemory(cStringLength + 1, 1); _s->cStringLength = cStringLength; _s->freeWhenDone = true; if (encoding == OFStringEncodingUTF8 || encoding == OFStringEncodingASCII) { switch (OFUTF8StringCheck(cString, cStringLength, &_s->length)) { case 1: if (encoding == OFStringEncodingASCII) @throw [OFInvalidEncodingException exception]; _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } memcpy(_s->cString, cString, cStringLength); _s->cString[cStringLength] = 0; return self; } /* All other encodings we support are single byte encodings */ _s->length = cStringLength; if (encoding == OFStringEncodingISO8859_1) { j = 0; for (size_t i = 0; i < cStringLength; i++) { char buffer[4]; size_t bytes; if (!(cString[i] & 0x80)) { _s->cString[j++] = cString[i]; continue; } _s->isUTF8 = true; bytes = OFUTF8StringEncode( (uint8_t)cString[i], buffer); if (bytes == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += bytes - 1; _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + 1, 1); memcpy(_s->cString + j, buffer, bytes); j += bytes; } _s->cString[_s->cStringLength] = 0; return self; } switch (encoding) { #define CASE(encoding, var) \ case encoding: \ table = var; \ tableOffset = var##Offset; \ break; #ifdef HAVE_ISO_8859_2 CASE(OFStringEncodingISO8859_2, OFISO8859_2Table) #endif #ifdef HAVE_ISO_8859_3 CASE(OFStringEncodingISO8859_3, OFISO8859_3Table) #endif #ifdef HAVE_ISO_8859_15 CASE(OFStringEncodingISO8859_15, OFISO8859_15Table) #endif #ifdef HAVE_WINDOWS_1251 CASE(OFStringEncodingWindows1251, OFWindows1251Table) #endif #ifdef HAVE_WINDOWS_1252 CASE(OFStringEncodingWindows1252, OFWindows1252Table) #endif #ifdef HAVE_CODEPAGE_437 CASE(OFStringEncodingCodepage437, OFCodepage437Table) #endif #ifdef HAVE_CODEPAGE_850 CASE(OFStringEncodingCodepage850, OFCodepage850Table) #endif #ifdef HAVE_CODEPAGE_858 CASE(OFStringEncodingCodepage858, OFCodepage858Table) #endif #ifdef HAVE_MAC_ROMAN CASE(OFStringEncodingMacRoman, OFMacRomanTable) #endif #ifdef HAVE_KOI8_R CASE(OFStringEncodingKOI8R, OFKOI8RTable) #endif #ifdef HAVE_KOI8_U CASE(OFStringEncodingKOI8U, OFKOI8UTable) #endif #undef CASE default: @throw [OFInvalidEncodingException exception]; } j = 0; for (size_t i = 0; i < cStringLength; i++) { unsigned char character = (unsigned char)cString[i]; OFUnichar unichar; char buffer[4]; size_t byteLength; if (character < tableOffset) { _s->cString[j++] = cString[i]; continue; } unichar = table[character - tableOffset]; if (unichar == 0xFFFF) @throw [OFInvalidEncodingException exception]; _s->isUTF8 = true; byteLength = OFUTF8StringEncode(unichar, buffer); if (byteLength == 0) @throw [OFInvalidEncodingException exception]; _s->cStringLength += byteLength - 1; _s->cString = OFResizeMemory(_s->cString, _s->cStringLength + 1, 1); memcpy(_s->cString + j, buffer, byteLength); j += byteLength; } _s->cString[_s->cStringLength] = 0; } @catch (id e) { |
︙ | ︙ | |||
400 401 402 403 404 405 406 | } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { | < | < < < < < < < < < < < | > > > > | 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | } - (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String length: (size_t)UTF8StringLength freeWhenDone: (bool)freeWhenDone { self = [super init]; @try { _s = &_storage; if (UTF8StringLength >= 3 && memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) { UTF8String += 3; UTF8StringLength -= 3; } switch (OFUTF8StringCheck(UTF8String, UTF8StringLength, &_s->length)) { case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } _s->cString = (char *)UTF8String; _s->cStringLength = UTF8StringLength; _s->freeWhenDone = freeWhenDone; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
456 457 458 459 460 461 462 | [string isKindOfClass: [OFMutableUTF8String class]]) _s->isUTF8 = ((OFUTF8String *)string)->_s->isUTF8; else _s->isUTF8 = true; _s->length = string.length; | | > | | > | | < | | | | > | | | | | | < | | | | > | > | | 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 | [string isKindOfClass: [OFMutableUTF8String class]]) _s->isUTF8 = ((OFUTF8String *)string)->_s->isUTF8; else _s->isUTF8 = true; _s->length = string.length; _s->cString = OFAllocMemory(_s->cStringLength + 1, 1); memcpy(_s->cString, string.UTF8String, _s->cStringLength + 1); _s->freeWhenDone = true; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithCharacters: (const OFUnichar *)characters length: (size_t)length { self = [super init]; @try { size_t j; _s = &_storage; _s->cString = OFAllocMemory((length * 4) + 1, 1); _s->length = length; _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { size_t len = OFUTF8StringEncode(characters[i], _s->cString + j); if (len == 0) @throw [OFInvalidEncodingException exception]; if (len > 1) _s->isUTF8 = true; j += len; } _s->cString[j] = '\0'; _s->cStringLength = j; @try { _s->cString = OFResizeMemory(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithUTF16String: (const OFChar16 *)string length: (size_t)length byteOrder: (OFByteOrder)byteOrder { self = [super init]; @try { size_t j; bool swap = false; if (length > 0 && *string == 0xFEFF) { string++; length--; } else if (length > 0 && *string == 0xFFFE) { swap = true; string++; length--; } else if (byteOrder != OFByteOrderNative) swap = true; _s = &_storage; _s->cString = OFAllocMemory((length * 4) + 1, 1); _s->length = length; _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { OFUnichar character = (swap ? OFByteSwap16(string[i]) : string[i]); size_t len; /* Missing high surrogate */ if ((character & 0xFC00) == 0xDC00) @throw [OFInvalidEncodingException exception]; if ((character & 0xFC00) == 0xD800) { OFChar16 nextCharacter; if (length <= i + 1) @throw [OFInvalidEncodingException exception]; nextCharacter = (swap ? OFByteSwap16(string[i + 1]) : string[i + 1]); if ((nextCharacter & 0xFC00) != 0xDC00) @throw [OFInvalidEncodingException exception]; character = (((character & 0x3FF) << 10) | (nextCharacter & 0x3FF)) + 0x10000; i++; _s->length--; } len = OFUTF8StringEncode(character, _s->cString + j); if (len == 0) @throw [OFInvalidEncodingException exception]; if (len > 1) _s->isUTF8 = true; j += len; } _s->cString[j] = '\0'; _s->cStringLength = j; @try { _s->cString = OFResizeMemory(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithUTF32String: (const OFChar32 *)characters length: (size_t)length byteOrder: (OFByteOrder)byteOrder { self = [super init]; @try { size_t j; bool swap = false; if (length > 0 && *characters == 0xFEFF) { characters++; length--; } else if (length > 0 && *characters == 0xFFFE0000) { swap = true; characters++; length--; } else if (byteOrder != OFByteOrderNative) swap = true; _s = &_storage; _s->cString = OFAllocMemory((length * 4) + 1, 1); _s->length = length; _s->freeWhenDone = true; j = 0; for (size_t i = 0; i < length; i++) { char buffer[4]; size_t len = OFUTF8StringEncode((swap ? OFByteSwap32(characters[i]) : characters[i]), buffer); switch (len) { case 1: _s->cString[j++] = buffer[0]; break; case 2: |
︙ | ︙ | |||
649 650 651 652 653 654 655 | } } _s->cString[j] = '\0'; _s->cStringLength = j; @try { | | < | 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 | } } _s->cString[j] = '\0'; _s->cStringLength = j; @try { _s->cString = OFResizeMemory(_s->cString, j + 1, 1); } @catch (OFOutOfMemoryException *e) { /* We don't care, as we only tried to make it smaller */ } } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
676 677 678 679 680 681 682 | int cStringLength; if (format == nil) @throw [OFInvalidArgumentException exception]; _s = &_storage; | | | | < > | | | | | | | | | | | | | | | | | | < | | | < | | | < | | | | | | | | | | < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 | int cStringLength; if (format == nil) @throw [OFInvalidArgumentException exception]; _s = &_storage; if ((cStringLength = OFVASPrintF(&tmp, format.UTF8String, arguments)) == -1) @throw [OFInvalidFormatException exception]; _s->cStringLength = cStringLength; @try { switch (OFUTF8StringCheck(tmp, cStringLength, &_s->length)) { case 1: _s->isUTF8 = true; break; case -1: @throw [OFInvalidEncodingException exception]; } _s->cString = OFAllocMemory(cStringLength + 1, 1); memcpy(_s->cString, tmp, cStringLength + 1); _s->freeWhenDone = true; } @finally { OFFreeMemory(tmp); } } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_s != NULL && _s->freeWhenDone) OFFreeMemory(_s->cString); [super dealloc]; } - (size_t)getCString: (char *)cString maxLength: (size_t)maxLength encoding: (OFStringEncoding)encoding { switch (encoding) { case OFStringEncodingASCII: if (_s->isUTF8) @throw [OFInvalidEncodingException exception]; /* intentional fall-through */ case OFStringEncodingUTF8: if (_s->cStringLength + 1 > maxLength) @throw [OFOutOfRangeException exception]; memcpy(cString, _s->cString, _s->cStringLength + 1); return _s->cStringLength; default: return [super getCString: cString maxLength: maxLength encoding: encoding]; } } - (const char *)cStringWithEncoding: (OFStringEncoding)encoding { switch (encoding) { case OFStringEncodingASCII: if (_s->isUTF8) @throw [OFInvalidEncodingException exception]; /* intentional fall-through */ case OFStringEncodingUTF8: return _s->cString; default: return [super cStringWithEncoding: encoding]; } } - (const char *)UTF8String { return _s->cString; } - (size_t)length { return _s->length; } - (size_t)cStringLengthWithEncoding: (OFStringEncoding)encoding { switch (encoding) { case OFStringEncodingUTF8: case OFStringEncodingASCII: return _s->cStringLength; default: return [super cStringLengthWithEncoding: encoding]; } } - (size_t)UTF8StringLength { return _s->cStringLength; } - (bool)isEqual: (id)object { OFUTF8String *string; if (object == self) return true; if (![object isKindOfClass: [OFString class]]) return false; string = object; if (string.UTF8StringLength != _s->cStringLength || string.length != _s->length) return false; if (([string isKindOfClass: [OFUTF8String class]] || [string isKindOfClass: [OFMutableUTF8String class]]) && _s->hasHash && string->_s->hasHash && _s->hash != string->_s->hash) return false; if (strcmp(_s->cString, string.UTF8String) != 0) return false; return true; } - (OFComparisonResult)compare: (OFString *)string { size_t otherCStringLength, minimumCStringLength; int compare; if (string == self) return OFOrderedSame; if (![string isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; otherCStringLength = string.UTF8StringLength; minimumCStringLength = (_s->cStringLength > otherCStringLength ? otherCStringLength : _s->cStringLength); if ((compare = memcmp(_s->cString, string.UTF8String, minimumCStringLength)) == 0) { if (_s->cStringLength > otherCStringLength) return OFOrderedDescending; if (_s->cStringLength < otherCStringLength) return OFOrderedAscending; return OFOrderedSame; } if (compare > 0) return OFOrderedDescending; else return OFOrderedAscending; } - (OFComparisonResult)caseInsensitiveCompare: (OFString *)string { const char *otherCString; size_t otherCStringLength, minimumCStringLength; #ifdef OF_HAVE_UNICODE_TABLES size_t i, j; #endif int compare; if (string == self) return OFOrderedSame; otherCString = string.UTF8String; otherCStringLength = string.UTF8StringLength; #ifdef OF_HAVE_UNICODE_TABLES if (!_s->isUTF8) { #endif minimumCStringLength = (_s->cStringLength > otherCStringLength ? otherCStringLength : _s->cStringLength); if ((compare = memcasecmp(_s->cString, otherCString, minimumCStringLength)) == 0) { if (_s->cStringLength > otherCStringLength) return OFOrderedDescending; if (_s->cStringLength < otherCStringLength) return OFOrderedAscending; return OFOrderedSame; } if (compare > 0) return OFOrderedDescending; else return OFOrderedAscending; #ifdef OF_HAVE_UNICODE_TABLES } i = j = 0; while (i < _s->cStringLength && j < otherCStringLength) { OFUnichar c1, c2; ssize_t l1, l2; l1 = OFUTF8StringDecode(_s->cString + i, _s->cStringLength - i, &c1); l2 = OFUTF8StringDecode(otherCString + j, otherCStringLength - j, &c2); if (l1 <= 0 || l2 <= 0 || c1 > 0x10FFFF || c2 > 0x10FFFF) @throw [OFInvalidEncodingException exception]; if (c1 >> 8 < OFUnicodeCaseFoldingTableSize) { OFUnichar tc = OFUnicodeCaseFoldingTable[c1 >> 8][c1 & 0xFF]; if (tc) c1 = tc; } if (c2 >> 8 < OFUnicodeCaseFoldingTableSize) { OFUnichar tc = OFUnicodeCaseFoldingTable[c2 >> 8][c2 & 0xFF]; if (tc) c2 = tc; } if (c1 > c2) return OFOrderedDescending; if (c1 < c2) return OFOrderedAscending; i += l1; j += l2; } if (_s->cStringLength - i > otherCStringLength - j) return OFOrderedDescending; else if (_s->cStringLength - i < otherCStringLength - j) return OFOrderedAscending; #endif return OFOrderedSame; } - (unsigned long)hash { unsigned long hash; if (_s->hasHash) return _s->hash; OFHashInit(&hash); for (size_t i = 0; i < _s->cStringLength; i++) { OFUnichar c; ssize_t length; if ((length = OFUTF8StringDecode(_s->cString + i, _s->cStringLength - i, &c)) <= 0) @throw [OFInvalidEncodingException exception]; OFHashAdd(&hash, (c & 0xFF0000) >> 16); OFHashAdd(&hash, (c & 0x00FF00) >> 8); OFHashAdd(&hash, c & 0x0000FF); i += length - 1; } OFHashFinalize(&hash); _s->hash = hash; _s->hasHash = true; return hash; } - (OFUnichar)characterAtIndex: (size_t)idx { OFUnichar character; if (idx >= _s->length) @throw [OFOutOfRangeException exception]; if (!_s->isUTF8) return _s->cString[idx]; idx = OFUTF8StringIndexToPosition(_s->cString, idx, _s->cStringLength); if (OFUTF8StringDecode(_s->cString + idx, _s->cStringLength - idx, &character) <= 0) @throw [OFInvalidEncodingException exception]; return character; } - (void)getCharacters: (OFUnichar *)buffer inRange: (OFRange)range { /* TODO: Could be slightly optimized */ void *pool = objc_autoreleasePoolPush(); const OFUnichar *characters = self.characters; if (range.length > SIZE_MAX - range.location || range.location + range.length > _s->length) @throw [OFOutOfRangeException exception]; memcpy(buffer, characters + range.location, range.length * sizeof(OFUnichar)); objc_autoreleasePoolPop(pool); } - (OFRange)rangeOfString: (OFString *)string options: (OFStringSearchOptions)options range: (OFRange)range { const char *cString = string.UTF8String; size_t cStringLength = string.UTF8StringLength; size_t rangeLocation, rangeLength; if (range.length > SIZE_MAX - range.location || range.location + range.length > _s->length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) { rangeLocation = OFUTF8StringIndexToPosition( _s->cString, range.location, _s->cStringLength); rangeLength = OFUTF8StringIndexToPosition( _s->cString + rangeLocation, range.length, _s->cStringLength - rangeLocation); } else { rangeLocation = range.location; rangeLength = range.length; } if (cStringLength == 0) return OFRangeMake(0, 0); if (cStringLength > rangeLength) return OFRangeMake(OFNotFound, 0); if (options & OFStringSearchBackwards) { for (size_t i = rangeLength - cStringLength;; i--) { if (memcmp(_s->cString + rangeLocation + i, cString, cStringLength) == 0) { range.location += positionToIndex( _s->cString + rangeLocation, i); range.length = string.length; return range; } /* Did not match and we're at the last char */ if (i == 0) return OFRangeMake(OFNotFound, 0); } } else { for (size_t i = 0; i <= rangeLength - cStringLength; i++) { if (memcmp(_s->cString + rangeLocation + i, cString, cStringLength) == 0) { range.location += positionToIndex( _s->cString + rangeLocation, i); range.length = string.length; return range; } } } return OFRangeMake(OFNotFound, 0); } - (bool)containsString: (OFString *)string { const char *cString = string.UTF8String; size_t cStringLength = string.UTF8StringLength; if (cStringLength == 0) return true; if (cStringLength > _s->cStringLength) return false; for (size_t i = 0; i <= _s->cStringLength - cStringLength; i++) if (memcmp(_s->cString + i, cString, cStringLength) == 0) return true; return false; } - (OFString *)substringWithRange: (OFRange)range { size_t start = range.location; size_t end = range.location + range.length; if (range.length > SIZE_MAX - range.location || end > _s->length) @throw [OFOutOfRangeException exception]; if (_s->isUTF8) { start = OFUTF8StringIndexToPosition(_s->cString, start, _s->cStringLength); end = OFUTF8StringIndexToPosition(_s->cString, end, _s->cStringLength); } return [OFString stringWithUTF8String: _s->cString + start length: end - start]; } |
︙ | ︙ | |||
1112 1113 1114 1115 1116 1117 1118 | return false; return (memcmp(_s->cString + (_s->cStringLength - cStringLength), suffix.UTF8String, cStringLength) == 0); } - (OFArray *)componentsSeparatedByString: (OFString *)delimiter | | | | | > > > > > > > > | 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 | return false; return (memcmp(_s->cString + (_s->cStringLength - cStringLength), suffix.UTF8String, cStringLength) == 0); } - (OFArray *)componentsSeparatedByString: (OFString *)delimiter options: (OFStringSeparationOptions)options { void *pool; OFMutableArray *array; const char *cString; size_t cStringLength; bool skipEmpty = (options & OFStringSkipEmptyComponents); size_t last; OFString *component; if (delimiter == nil) @throw [OFInvalidArgumentException exception]; if (delimiter.length == 0) return [OFArray arrayWithObject: self]; array = [OFMutableArray array]; pool = objc_autoreleasePoolPush(); cString = delimiter.UTF8String; cStringLength = delimiter.UTF8StringLength; if (cStringLength > _s->cStringLength) { [array addObject: [[self copy] autorelease]]; objc_autoreleasePoolPop(pool); return array; } |
︙ | ︙ | |||
1156 1157 1158 1159 1160 1161 1162 | [array makeImmutable]; objc_autoreleasePoolPop(pool); return array; } | | < | | | < < < < | | | > | > | > > > > > > > > > > | < | | | < < < < | | | > | > | | | | > > > > > > > > > > | | < | > | 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 | [array makeImmutable]; objc_autoreleasePoolPop(pool); return array; } - (const OFUnichar *)characters { OFUnichar *buffer = OFAllocMemory(_s->length, sizeof(OFUnichar)); size_t i = 0, j = 0; const OFUnichar *ret; while (i < _s->cStringLength) { OFUnichar c; ssize_t cLen; cLen = OFUTF8StringDecode(_s->cString + i, _s->cStringLength - i, &c); if (cLen <= 0 || c > 0x10FFFF) { OFFreeMemory(buffer); @throw [OFInvalidEncodingException exception]; } buffer[j++] = c; i += cLen; } @try { ret = [[OFData dataWithItemsNoCopy: buffer count: _s->length itemSize: sizeof(OFUnichar) freeWhenDone: true] items]; } @catch (id e) { OFFreeMemory(buffer); @throw e; } return ret; } - (const OFChar32 *)UTF32StringWithByteOrder: (OFByteOrder)byteOrder { OFChar32 *buffer = OFAllocMemory(_s->length + 1, sizeof(OFChar32)); size_t i = 0, j = 0; const OFChar32 *ret; while (i < _s->cStringLength) { OFChar32 c; ssize_t cLen; cLen = OFUTF8StringDecode(_s->cString + i, _s->cStringLength - i, &c); if (cLen <= 0 || c > 0x10FFFF) { OFFreeMemory(buffer); @throw [OFInvalidEncodingException exception]; } if (byteOrder != OFByteOrderNative) buffer[j++] = OFByteSwap32(c); else buffer[j++] = c; i += cLen; } buffer[j] = 0; @try { ret = [[OFData dataWithItemsNoCopy: buffer count: _s->length + 1 itemSize: sizeof(OFChar32) freeWhenDone: true] items]; } @catch (id e) { OFFreeMemory(buffer); @throw e; } return ret; } #ifdef OF_HAVE_BLOCKS - (void)enumerateLinesUsingBlock: (OFStringLineEnumerationBlock)block { void *pool; const char *cString = _s->cString; const char *last = cString; bool stop = false, lastCarriageReturn = false; while (!stop && *cString != 0) { if (lastCarriageReturn && *cString == '\n') { lastCarriageReturn = false; cString++; last++; continue; } if (*cString == '\n' || *cString == '\r') { pool = objc_autoreleasePoolPush(); block([OFString stringWithUTF8String: last length: cString - last], &stop); last = cString + 1; objc_autoreleasePoolPop(pool); } lastCarriageReturn = (*cString == '\r'); cString++; |
︙ | ︙ |
Added src/OFUUID.h version [e7cc13e47d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFSerialization.h" OF_ASSUME_NONNULL_BEGIN @class OFString; /** * @class OFUUID OFUUID.h ObjFW/OFUUID.h * * @brief A UUID conforming to RFC 4122. */ OF_SUBCLASSING_RESTRICTED @interface OFUUID: OFObject <OFCopying, OFComparing, OFSerialization> { unsigned char _bytes[16]; } /** * @brief The UUID as a string. */ @property (readonly, nonatomic) OFString *UUIDString; /** * @brief Creates a new random UUID as per RFC 4122 version 4. * * @return A new, autoreleased OFUUID */ + (instancetype)UUID; /** * @brief Creates a new UUID with the specified bytes. * * @param bytes The bytes for the UUID * @return A new, autoreleased OFUUID */ + (instancetype)UUIDWithUUIDBytes: (const unsigned char [_Nonnull 16])bytes; /** * @brief Creates a new UUID with the specified UUID string. * * @param string The UUID string for the UUID * @return A new, autoreleased OFUUID */ + (instancetype)UUIDWithUUIDString: (OFString *)string; /** * @brief Initializes an already allocated OFUUID as a new random UUID as per * RFC 4122 version 4. * * @return An initialized OFUUID */ - (instancetype)init; /** * @brief Initializes an already allocated OFUUID with the specified bytes. * * @param bytes The bytes to initialize the OFUUID with * @return An initialized OFUUID */ - (instancetype)initWithUUIDBytes: (const unsigned char [_Nonnull 16])bytes; /** * @brief Initializes an already allocated OFUUID with the specified UUID * string. * * @param string The UUID string to initialize the OFUUID with * @return An initialized OFUUID */ - (instancetype)initWithUUIDString: (OFString *)string; /** * @brief Compares the UUID to another UUID. * * @param UUID The UUID to compare to * @return The result of the comparison */ - (OFComparisonResult)compare: (OFUUID *)UUID; /** * @brief Gets the bytes of the UUID. * * @param bytes An array of 16 bytes into which to write the UUID */ - (void)getUUIDBytes: (unsigned char [_Nonnull 16])bytes; @end OF_ASSUME_NONNULL_END |
Added src/OFUUID.m version [2113b35dea].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFUUID.h" #import "OFArray.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #define bytesSize 16 @implementation OFUUID + (instancetype)UUID { return [[[self alloc] init] autorelease]; } + (instancetype)UUIDWithUUIDBytes: (const unsigned char [16])bytes { return [[[self alloc] initWithUUIDBytes: bytes] autorelease]; } + (instancetype)UUIDWithUUIDString: (OFString *)string { return [[[self alloc] initWithUUIDString: string] autorelease]; } - (instancetype)init { uint64_t r; self = [super init]; r = OFRandom64(); memcpy(_bytes, &r, 8); r = OFRandom64(); memcpy(_bytes + 8, &r, 8); _bytes[6] &= ~((1 << 7) | (1 << 5) | (1 << 4)); _bytes[6] |= (1 << 6); _bytes[8] &= ~(1 << 6); _bytes[8] |= (1 << 7); return self; } - (instancetype)initWithUUIDBytes: (const unsigned char [16])bytes { self = [super init]; memcpy(_bytes, bytes, sizeof(_bytes)); return self; } static void decode(OFArray OF_GENERIC(OFString *) *components, size_t componentIndex, size_t componentLength, unsigned char *bytes, size_t *i) { void *pool = objc_autoreleasePoolPush(); OFString *component = [components objectAtIndex: componentIndex]; const char *cString; if (component.UTF8StringLength != componentLength) @throw [OFInvalidFormatException exception]; if (*i + componentLength / 2 > bytesSize) @throw [OFOutOfRangeException exception]; cString = component.UTF8String; for (size_t j = 0; j < componentLength; j += 2) { uint8_t value; if (cString[j] >= '0' && cString[j] <= '9') value = cString[j] - '0'; else if (cString[j] >= 'a' && cString[j] <= 'f') value = cString[j] - 'a' + 10; else if (cString[j] >= 'A' && cString[j] <= 'F') value = cString[j] - 'A' + 10; else @throw [OFInvalidFormatException exception]; value <<= 4; if (cString[j + 1] >= '0' && cString[j + 1] <= '9') value |= cString[j + 1] - '0'; else if (cString[j + 1] >= 'a' && cString[j + 1] <= 'f') value |= cString[j + 1] - 'a' + 10; else if (cString[j + 1] >= 'A' && cString[j + 1] <= 'F') value |= cString[j + 1] - 'A' + 10; else @throw [OFInvalidFormatException exception]; bytes[(*i)++] = value; } objc_autoreleasePoolPop(pool); } - (instancetype)initWithUUIDString: (OFString *)string { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); size_t i = 0; OFArray OF_GENERIC(OFString *) *components = [string componentsSeparatedByString: @"-"]; if (components.count != 5) @throw [OFInvalidFormatException exception]; decode(components, 0, 8, _bytes, &i); decode(components, 1, 4, _bytes, &i); decode(components, 2, 4, _bytes, &i); decode(components, 3, 4, _bytes, &i); decode(components, 4, 12, _bytes, &i); OFEnsure(i == 16); objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { void *pool = objc_autoreleasePoolPush(); OFString *UUIDString; @try { if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; UUIDString = element.stringValue; } @catch (id e) { [self release]; @throw e; } self = [self initWithUUIDString: UUIDString]; objc_autoreleasePoolPop(pool); return self; } - (bool)isEqual: (id)object { OFUUID *UUID; if (![object isKindOfClass: [OFUUID class]]) return false; UUID = object; return (memcmp(_bytes, UUID->_bytes, sizeof(_bytes)) == 0); } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); for (size_t i = 0; i < sizeof(_bytes); i++) OFHashAdd(&hash, _bytes[i]); OFHashFinalize(&hash); return hash; } - (id)copy { return [self retain]; } - (OFComparisonResult)compare: (OFUUID *)UUID { int comparison; if (![UUID isKindOfClass: [OFUUID class]]) @throw [OFInvalidArgumentException exception]; if ((comparison = memcmp(_bytes, UUID->_bytes, sizeof(_bytes))) == 0) return OFOrderedSame; if (comparison > 0) return OFOrderedDescending; else return OFOrderedAscending; } - (void)getUUIDBytes: (unsigned char [16])bytes { memcpy(bytes, _bytes, sizeof(_bytes)); } - (OFString *)UUIDString { return [OFString stringWithFormat: @"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" @"%02x%02x%02x%02x%02x%02x", _bytes[0], _bytes[1], _bytes[2], _bytes[3], _bytes[4], _bytes[5], _bytes[6], _bytes[7], _bytes[8], _bytes[9], _bytes[10], _bytes[11], _bytes[12], _bytes[13], _bytes[14], _bytes[15]]; } - (OFString *)description { return self.UUIDString; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS stringValue: self.UUIDString]; [element retain]; objc_autoreleasePoolPop(pool); return [element autorelease]; } @end |
Modified src/OFValue.h from [e9a82ba4b1] to [823407a4d9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
45 46 47 48 49 50 51 | * @brief The value as a non-retained object. * * If the value is not pointer-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) id nonretainedObjectValue; /** | | | | | | | | | | | | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | * @brief The value as a non-retained object. * * If the value is not pointer-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) id nonretainedObjectValue; /** * @brief The value as an OFRange. * * If the value is not OFRange-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) OFRange rangeValue; /** * @brief The value as an OFPoint. * * If the value is not OFPoint-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) OFPoint pointValue; /** * @brief The value as an OFSize. * * If the value is not OFSize-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) OFSize sizeValue; /** * @brief The value as a OFRect. * * If the value is not OFRect-sized, @ref OFOutOfRangeException is thrown. */ @property (readonly, nonatomic) OFRect rectValue; /** * @brief Creates a new, autorelease OFValue with the specified bytes of the * specified type. * * @param bytes The bytes containing the value * @param objCType The ObjC type encoding for the value |
︙ | ︙ | |||
111 112 113 114 115 116 117 | /** * @brief Creates a new, autoreleased OFValue containing the specified range. * * @param range The range the OFValue should contain * @return A new, autoreleased OFValue */ | | | | < | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | /** * @brief Creates a new, autoreleased OFValue containing the specified range. * * @param range The range the OFValue should contain * @return A new, autoreleased OFValue */ + (instancetype)valueWithRange: (OFRange)range; /** * @brief Creates a new, autoreleased OFValue containing the specified point. * * @param point The point the OFValue should contain * @return A new, autoreleased OFValue */ + (instancetype)valueWithPoint: (OFPoint)point; /** * @brief Creates a new, autoreleased OFValue containing the specified size. * * @param size The size the OFValue should contain * @return A new, autoreleased OFValue */ + (instancetype)valueWithSize: (OFSize)size; /** * @brief Creates a new, autoreleased OFValue containing the specified * rectangle. * * @param rect The rectangle the OFValue should contain * @return A new, autoreleased OFValue */ + (instancetype)valueWithRect: (OFRect)rect; /** * @brief Initializes an already allocated OFValue with the specified bytes of * the specified type. * * @param bytes The bytes containing the value * @param objCType The ObjC type encoding for the value * @return An initialized OFValue */ - (instancetype)initWithBytes: (const void *)bytes objCType: (const char *)objCType; /** * @brief Gets the value. * * If the specified size does not match, this raises an * @ref OFOutOfRangeException. * * @param value The buffer to copy the value into * @param size The size of the value */ - (void)getValue: (void *)value size: (size_t)size; @end OF_ASSUME_NONNULL_END #if !defined(NSINTEGER_DEFINED) && !__has_feature(modules) /* Required for array literals to work */ @compatibility_alias NSValue OFValue; #endif |
Modified src/OFValue.m from [1029a1bdaf] to [4253491c94].
1 | /* | < < | < | > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | > | | | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFValue.h" #import "OFBytesValue.h" #import "OFMethodSignature.h" #import "OFNonretainedObjectValue.h" #import "OFPointValue.h" #import "OFPointerValue.h" #import "OFRangeValue.h" #import "OFRectValue.h" #import "OFSizeValue.h" #import "OFString.h" #import "OFOutOfMemoryException.h" @implementation OFValue + (instancetype)alloc { if (self == [OFValue class]) return [OFBytesValue alloc]; return [super alloc]; } + (instancetype)valueWithBytes: (const void *)bytes objCType: (const char *)objCType { return [[[OFBytesValue alloc] initWithBytes: bytes objCType: objCType] autorelease]; } + (instancetype)valueWithPointer: (const void *)pointer { return [[[OFPointerValue alloc] initWithPointer: pointer] autorelease]; } + (instancetype)valueWithNonretainedObject: (id)object { return [[[OFNonretainedObjectValue alloc] initWithNonretainedObject: object] autorelease]; } + (instancetype)valueWithRange: (OFRange)range { return [[[OFRangeValue alloc] initWithRange: range] autorelease]; } + (instancetype)valueWithPoint: (OFPoint)point { return [[[OFPointValue alloc] initWithPoint: point] autorelease]; } + (instancetype)valueWithSize: (OFSize)size { return [[[OFSizeValue alloc] initWithSize: size] autorelease]; } + (instancetype)valueWithRect: (OFRect)rect { return [[[OFRectValue alloc] initWithRect: rect] autorelease]; } - (instancetype)initWithBytes: (const void *)bytes objCType: (const char *)objCType { OF_INVALID_INIT_METHOD } - (bool)isEqual: (id)object { const char *objCType; size_t size; |
︙ | ︙ | |||
177 178 179 180 181 182 183 | return false; objCType = self.objCType; if (strcmp([object objCType], objCType) != 0) return false; | | | | | | < | < < | | | | | | < | | | | | < < | < < < | < < | < | | < < | | < < | < | | < | < < | | < | < < | | | < | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | return false; objCType = self.objCType; if (strcmp([object objCType], objCType) != 0) return false; size = OFSizeOfTypeEncoding(objCType); value = OFAllocMemory(1, size); @try { otherValue = OFAllocMemory(1, size); } @catch (id e) { OFFreeMemory(value); @throw e; } @try { [self getValue: value size: size]; [object getValue: otherValue size: size]; ret = (memcmp(value, otherValue, size) == 0); } @finally { OFFreeMemory(value); OFFreeMemory(otherValue); } return ret; } - (unsigned long)hash { size_t size = OFSizeOfTypeEncoding(self.objCType); unsigned char *value; unsigned long hash; value = OFAllocMemory(1, size); @try { [self getValue: value size: size]; OFHashInit(&hash); for (size_t i = 0; i < size; i++) OFHashAdd(&hash, value[i]); OFHashFinalize(&hash); } @finally { OFFreeMemory(value); } return hash; } - (id)copy { return [self retain]; } - (const char *)objCType { OF_UNRECOGNIZED_SELECTOR } - (void)getValue: (void *)value size: (size_t)size { OF_UNRECOGNIZED_SELECTOR } - (void *)pointerValue { void *ret; [self getValue: &ret size: sizeof(ret)]; return ret; } - (id)nonretainedObjectValue { id ret; [self getValue: &ret size: sizeof(ret)]; return ret; } - (OFRange)rangeValue { OFRange ret; [self getValue: &ret size: sizeof(ret)]; return ret; } - (OFPoint)pointValue { OFPoint ret; [self getValue: &ret size: sizeof(ret)]; return ret; } - (OFSize)sizeValue { OFSize ret; [self getValue: &ret size: sizeof(ret)]; return ret; } - (OFRect)rectValue { OFRect ret; [self getValue: &ret size: sizeof(ret)]; return ret; } - (OFString *)description { OFMutableString *ret = [OFMutableString stringWithString: @"<OFValue: "]; size_t size = OFSizeOfTypeEncoding(self.objCType); unsigned char *value; value = OFAllocMemory(1, size); @try { [self getValue: value size: size]; for (size_t i = 0; i < size; i++) { if (i > 0) [ret appendString: @" "]; [ret appendFormat: @"%02x", value[i]]; } } @finally { OFFreeMemory(value); } [ret appendString: @">"]; [ret makeImmutable]; return ret; } @end |
Modified src/OFWin32ConsoleStdIOStream.h from [77f92f2723] to [d9940ccf28].
1 | /* | < < | < < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFStdIOStream.h" OF_ASSUME_NONNULL_BEGIN @interface OFWin32ConsoleStdIOStream: OFStdIOStream { HANDLE _handle; WORD _attributes; OFChar16 _incompleteUTF16Surrogate; char _incompleteUTF8Surrogate[4]; size_t _incompleteUTF8SurrogateLen; } @end OF_ASSUME_NONNULL_END |
Modified src/OFWin32ConsoleStdIOStream.m from [959c780c29] to [8c3f9ce8af].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | * For example, on Windows XP, when using Windows XP's console, changing the * codepage to UTF-8 mostly breaks write() and completely breaks read(): * write() suddenly returns the number of characters - instead of bytes - * written and read() just returns 0 as soon as a Unicode character is being * read. * * Therefore, instead of just using the UTF-8 codepage, this captures all reads | | < < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | * For example, on Windows XP, when using Windows XP's console, changing the * codepage to UTF-8 mostly breaks write() and completely breaks read(): * write() suddenly returns the number of characters - instead of bytes - * written and read() just returns 0 as soon as a Unicode character is being * read. * * Therefore, instead of just using the UTF-8 codepage, this captures all reads * and writes to OFStd{In,Out,Err} on the low level, interprets the buffer as * UTF-8 and converts to / from UTF-16 to use ReadConsoleW() / WriteConsoleW(). * Doing so is safe, as the console only supports text anyway and thus it does * not matter if binary gets garbled by the conversion (e.g. because invalid * UTF-8 gets converted to U+FFFD). * * In order to not do this when redirecting input / output to a file (as the * file would then be read / written in the wrong encoding and break reading / * writing binary), it checks that the handle is indeed a console. */ #include "config.h" #include <assert.h> #include <errno.h> #include <io.h> #import "OFWin32ConsoleStdIOStream.h" |
︙ | ︙ | |||
58 59 60 61 62 63 64 | #import "OFInvalidEncodingException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #include <windows.h> | | | | | | | | | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | #import "OFInvalidEncodingException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #include <windows.h> static OFStringEncoding codepageToEncoding(UINT codepage) { switch (codepage) { case 437: return OFStringEncodingCodepage437; case 850: return OFStringEncodingCodepage850; case 858: return OFStringEncodingCodepage858; case 1251: return OFStringEncodingWindows1251; case 1252: return OFStringEncodingWindows1252; default: @throw [OFInvalidEncodingException exception]; } } @implementation OFWin32ConsoleStdIOStream + (void)load { int fd; if (self != [OFWin32ConsoleStdIOStream class]) return; if ((fd = _fileno(stdin)) >= 0) OFStdIn = [[OFWin32ConsoleStdIOStream alloc] of_initWithFileDescriptor: fd]; if ((fd = _fileno(stdout)) >= 0) OFStdOut = [[OFWin32ConsoleStdIOStream alloc] of_initWithFileDescriptor: fd]; if ((fd = _fileno(stderr)) >= 0) OFStdErr = [[OFWin32ConsoleStdIOStream alloc] of_initWithFileDescriptor: fd]; } - (instancetype)of_initWithFileDescriptor: (int)fd { self = [super of_initWithFileDescriptor: fd]; |
︙ | ︙ | |||
122 123 124 125 126 127 128 | [self release]; @throw e; } return self; } | | < | | < | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | [self release]; @throw e; } return self; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer_ length: (size_t)length { void *pool = objc_autoreleasePoolPush(); char *buffer = buffer_; OFChar16 *UTF16; size_t j = 0; if (length > UINT32_MAX) @throw [OFOutOfRangeException exception]; UTF16 = OFAllocMemory(length, sizeof(OFChar16)); @try { DWORD UTF16Len; OFMutableData *rest = nil; size_t i = 0; if ([OFSystemInfo isWindowsNT]) { if (!ReadConsoleW(_handle, UTF16, (DWORD)length, &UTF16Len, NULL)) @throw [OFReadFailedException exceptionWithObject: self requestedLength: length * 2 errNo: EIO]; } else { OFStringEncoding encoding; OFString *string; size_t stringLen; if (!ReadConsoleA(_handle, (char *)UTF16, (DWORD)length, &UTF16Len, NULL)) @throw [OFReadFailedException exceptionWithObject: self |
︙ | ︙ | |||
173 174 175 176 177 178 179 | @throw [OFOutOfRangeException exception]; UTF16Len = (DWORD)stringLen; memcpy(UTF16, string.UTF16String, stringLen); } if (UTF16Len > 0 && _incompleteUTF16Surrogate != 0) { | | | | < | | | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | @throw [OFOutOfRangeException exception]; UTF16Len = (DWORD)stringLen; memcpy(UTF16, string.UTF16String, stringLen); } if (UTF16Len > 0 && _incompleteUTF16Surrogate != 0) { OFUnichar c = (((_incompleteUTF16Surrogate & 0x3FF) << 10) | (UTF16[0] & 0x3FF)) + 0x10000; char UTF8[4]; size_t UTF8Len; if ((UTF8Len = OFUTF8StringEncode(c, UTF8)) == 0) @throw [OFInvalidEncodingException exception]; if (UTF8Len <= length) { memcpy(buffer, UTF8, UTF8Len); j += UTF8Len; } else { if (rest == nil) rest = [OFMutableData data]; [rest addItems: UTF8 count: UTF8Len]; } _incompleteUTF16Surrogate = 0; i++; } for (; i < UTF16Len; i++) { OFUnichar c = UTF16[i]; char UTF8[4]; size_t UTF8Len; /* Missing high surrogate */ if ((c & 0xFC00) == 0xDC00) @throw [OFInvalidEncodingException exception]; if ((c & 0xFC00) == 0xD800) { OFChar16 next; if (UTF16Len <= i + 1) { _incompleteUTF16Surrogate = c; if (rest != nil) { const char *items = rest.items; size_t count = rest.count; |
︙ | ︙ | |||
237 238 239 240 241 242 243 | c = (((c & 0x3FF) << 10) | (next & 0x3FF)) + 0x10000; i++; } | | | < | < | | < | | | | | | | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | c = (((c & 0x3FF) << 10) | (next & 0x3FF)) + 0x10000; i++; } if ((UTF8Len = OFUTF8StringEncode(c, UTF8)) == 0) @throw [OFInvalidEncodingException exception]; if (j + UTF8Len <= length) { memcpy(buffer + j, UTF8, UTF8Len); j += UTF8Len; } else { if (rest == nil) rest = [OFMutableData data]; [rest addItems: UTF8 count: UTF8Len]; } } if (rest != nil) [self unreadFromBuffer: rest.items length: rest.count]; } @finally { OFFreeMemory(UTF16); } objc_autoreleasePoolPop(pool); return j; } - (size_t)lowlevelWriteBuffer: (const void *)buffer_ length: (size_t)length { const char *buffer = buffer_; OFChar16 *tmp; size_t i = 0, j = 0; if (length > SIZE_MAX / 2) @throw [OFOutOfRangeException exception]; if (_incompleteUTF8SurrogateLen > 0) { OFUnichar c; OFChar16 UTF16[2]; ssize_t UTF8Len; size_t toCopy; DWORD UTF16Len, bytesWritten; UTF8Len = -OFUTF8StringDecode( _incompleteUTF8Surrogate, _incompleteUTF8SurrogateLen, &c); OFEnsure(UTF8Len > 0); toCopy = UTF8Len - _incompleteUTF8SurrogateLen; if (toCopy > length) toCopy = length; memcpy(_incompleteUTF8Surrogate + _incompleteUTF8SurrogateLen, buffer, toCopy); _incompleteUTF8SurrogateLen += toCopy; if (_incompleteUTF8SurrogateLen < (size_t)UTF8Len) return 0; UTF8Len = OFUTF8StringDecode( _incompleteUTF8Surrogate, _incompleteUTF8SurrogateLen, &c); if (UTF8Len <= 0 || c > 0x10FFFF) { assert(UTF8Len == 0 || UTF8Len < -4); UTF16[0] = 0xFFFD; UTF16Len = 1; |
︙ | ︙ | |||
330 331 332 333 334 335 336 | bytesWritten: bytesWritten * 2 errNo: EIO]; } else { void *pool = objc_autoreleasePoolPush(); OFString *string = [OFString stringWithUTF16String: UTF16 length: UTF16Len]; | | | 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | bytesWritten: bytesWritten * 2 errNo: EIO]; } else { void *pool = objc_autoreleasePoolPush(); OFString *string = [OFString stringWithUTF16String: UTF16 length: UTF16Len]; OFStringEncoding encoding = codepageToEncoding(GetConsoleOutputCP()); size_t nativeLen = [string cStringLengthWithEncoding: encoding]; if (nativeLen > UINT32_MAX) @throw [OFOutOfRangeException exception]; |
︙ | ︙ | |||
361 362 363 364 365 366 367 | bytesWritten: bytesWritten * 2 errNo: 0]; _incompleteUTF8SurrogateLen = 0; i += toCopy; } | < | | | | | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | bytesWritten: bytesWritten * 2 errNo: 0]; _incompleteUTF8SurrogateLen = 0; i += toCopy; } tmp = OFAllocMemory(length * 2, sizeof(OFChar16)); @try { DWORD bytesWritten; while (i < length) { OFUnichar c; ssize_t UTF8Len; UTF8Len = OFUTF8StringDecode(buffer + i, length - i, &c); if (UTF8Len < 0 && UTF8Len >= -4) { OFEnsure(length - i < 4); memcpy(_incompleteUTF8Surrogate, buffer + i, length - i); _incompleteUTF8SurrogateLen = length - i; break; } |
︙ | ︙ | |||
414 415 416 417 418 419 420 | requestedLength: j * 2 bytesWritten: bytesWritten * 2 errNo: EIO]; } else { void *pool = objc_autoreleasePoolPush(); OFString *string = [OFString stringWithUTF16String: tmp length: j]; | | | 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | requestedLength: j * 2 bytesWritten: bytesWritten * 2 errNo: EIO]; } else { void *pool = objc_autoreleasePoolPush(); OFString *string = [OFString stringWithUTF16String: tmp length: j]; OFStringEncoding encoding = codepageToEncoding(GetConsoleOutputCP()); size_t nativeLen = [string cStringLengthWithEncoding: encoding]; if (nativeLen > UINT32_MAX) @throw [OFOutOfRangeException exception]; |
︙ | ︙ | |||
441 442 443 444 445 446 447 | if (bytesWritten != j) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: j * 2 bytesWritten: bytesWritten * 2 errNo: 0]; } @finally { | | | 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | if (bytesWritten != j) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: j * 2 bytesWritten: bytesWritten * 2 errNo: 0]; } @finally { OFFreeMemory(tmp); } /* * We do not count in bytes when writing to the Win32 console. But * since any incomplete write is an exception here anyway, we can just * return length. */ |
︙ | ︙ | |||
491 492 493 494 495 496 497 | if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return; csbi.wAttributes &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); | | < < < | 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return; csbi.wAttributes &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); [color getRed: &red green: &green blue: &blue alpha: NULL]; if (red >= 0.25) csbi.wAttributes |= FOREGROUND_RED; if (green >= 0.25) csbi.wAttributes |= FOREGROUND_GREEN; if (blue >= 0.25) csbi.wAttributes |= FOREGROUND_BLUE; |
︙ | ︙ | |||
520 521 522 523 524 525 526 | if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return; csbi.wAttributes &= ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY); | | < < < | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 | if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return; csbi.wAttributes &= ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY); [color getRed: &red green: &green blue: &blue alpha: NULL]; if (red >= 0.25) csbi.wAttributes |= BACKGROUND_RED; if (green >= 0.25) csbi.wAttributes |= BACKGROUND_GREEN; if (blue >= 0.25) csbi.wAttributes |= BACKGROUND_BLUE; |
︙ | ︙ | |||
593 594 595 596 597 598 599 | return; csbi.dwCursorPosition.X = column; SetConsoleCursorPosition(_handle, csbi.dwCursorPosition); } | | | | 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 | return; csbi.dwCursorPosition.X = column; SetConsoleCursorPosition(_handle, csbi.dwCursorPosition); } - (void)setCursorPosition: (OFPoint)position { if (position.x < 0 || position.y < 0) @throw [OFInvalidArgumentException exception]; SetConsoleCursorPosition(_handle, (COORD){ position.x, position.y }); } - (void)setRelativeCursorPosition: (OFPoint)position { CONSOLE_SCREEN_BUFFER_INFO csbi; if (!GetConsoleScreenBufferInfo(_handle, &csbi)) return; csbi.dwCursorPosition.X += position.x; csbi.dwCursorPosition.Y += position.y; SetConsoleCursorPosition(_handle, csbi.dwCursorPosition); } @end |
Modified src/OFWindowsRegistryKey.h from [fcd22050ce] to [c114c8ff33].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
74 75 76 77 78 79 80 | /** * @brief Opens the subkey at the specified path. * * @param path The path of the subkey to open * @param securityAndAccessRights Please refer to the `RegOpenKeyEx()` * documentation for `samDesired` | | < | | | < | | | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | /** * @brief Opens the subkey at the specified path. * * @param path The path of the subkey to open * @param securityAndAccessRights Please refer to the `RegOpenKeyEx()` * documentation for `samDesired` * @return The subkey with the specified path */ - (OFWindowsRegistryKey *)openSubkeyAtPath: (OFString *)path securityAndAccessRights: (REGSAM)securityAndAccessRights; /** * @brief Opens the subkey at the specified path. * * @param path The path of the subkey to open * @param options Please refer to the `RegOpenKeyEx()` documentation for * `ulOptions`. Usually 0. * @param securityAndAccessRights Please refer to the `RegOpenKeyEx()` * documentation for `samDesired` * @return The subkey with the specified path */ - (OFWindowsRegistryKey *)openSubkeyAtPath: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights; /** * @brief Creates a subkey at the specified path or opens it if it already * exists. * * @param path The path of the subkey to create * @param securityAndAccessRights Please refer to the `RegCreateKeyEx()` |
︙ | ︙ | |||
134 135 136 137 138 139 140 | securityAndAccessRights: (REGSAM)securityAndAccessRights securityAttributes: (nullable SECURITY_ATTRIBUTES *)securityAttributes disposition: (nullable DWORD *)disposition; /** * @brief Returns the data for the specified value at the specified path. * | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | securityAndAccessRights: (REGSAM)securityAndAccessRights securityAttributes: (nullable SECURITY_ATTRIBUTES *)securityAttributes disposition: (nullable DWORD *)disposition; /** * @brief Returns the data for the specified value at the specified path. * * @param name The name of the value to return * @param type A pointer to store the type of the value, or NULL * @return The data for the specified value */ - (nullable OFData *)dataForValueNamed: (nullable OFString *)name type: (nullable DWORD *)type; /** * @brief Sets the data for the specified value. * * @param data The data to set the value to * @param name The name of the value to set * @param type The type for the value */ - (void)setData: (nullable OFData *)data forValueNamed: (nullable OFString *)name type: (DWORD)type; /** * @brief Returns the string for the specified value at the specified path. * * @param name The name of the value to return * @return The string for the specified value */ - (nullable OFString *)stringForValueNamed: (nullable OFString *)name; /** * @brief Returns the string for the specified value at the specified path. * * @param name The name of the value to return * @param type A pointer to store the type of the value, or NULL * @return The string for the specified value */ - (nullable OFString *)stringForValueNamed: (nullable OFString *)name type: (nullable DWORD *)type; /** * @brief Sets the string for the specified value. * * @param string The string to set the value to * @param name The name of the value to set */ - (void)setString: (nullable OFString *)string forValueNamed: (nullable OFString *)name; /** * @brief Sets the string for the specified value. * * @param string The string to set the value to * @param name The name of the value to set * @param type The type for the value */ - (void)setString: (nullable OFString *)string forValueNamed: (nullable OFString *)name type: (DWORD)type; /** * @brief Returns the DWORD for the specified value at the specified path. * * @param name The name of the value to return * @return The DWORD for the specified value */ - (uint32_t)DWORDForValueNamed: (nullable OFString *)name; /** * @brief Sets the DWORD for the specified value. * * @param dword The DWORD to set the value to * @param name The name of the value to set */ - (void)setDWORD: (uint32_t)dword forValueNamed: (nullable OFString *)name; /** * @brief Returns the QWORD for the specified value at the specified path. * * @param name The name of the value to return * @return The QWORD for the specified value */ - (uint64_t)QWORDForValueNamed: (nullable OFString *)name; /** * @brief Sets the QWORD for the specified value. * * @param qword The QWORD to set the value to * @param name The name of the value to set */ - (void)setQWORD: (uint64_t)qword forValueNamed: (nullable OFString *)name; /** * @brief Deletes the specified value. * * @param name The value to delete */ - (void)deleteValueNamed: (nullable OFString *)name; /** * @brief Deletes the specified subkey. * * @param subkeyPath The path of the subkey to delete */ - (void)deleteSubkeyAtPath: (OFString *)subkeyPath; @end OF_ASSUME_NONNULL_END |
Modified src/OFWindowsRegistryKey.m from [db8bc56ab6] to [d93d6521e9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 38 | #import "OFDeleteWindowsRegistryValueFailedException.h" #import "OFGetWindowsRegistryValueFailedException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOpenWindowsRegistryKeyFailedException.h" #import "OFOutOfRangeException.h" #import "OFSetWindowsRegistryValueFailedException.h" OF_DIRECT_MEMBERS @interface OFWindowsRegistryKey () | > | < | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #import "OFDeleteWindowsRegistryValueFailedException.h" #import "OFGetWindowsRegistryValueFailedException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFOpenWindowsRegistryKeyFailedException.h" #import "OFOutOfRangeException.h" #import "OFSetWindowsRegistryValueFailedException.h" #import "OFUndefinedKeyException.h" OF_DIRECT_MEMBERS @interface OFWindowsRegistryKey () - (instancetype)of_initWithHKey: (HKEY)hKey close: (bool)close; @end @implementation OFWindowsRegistryKey + (instancetype)classesRootKey { return [[[self alloc] of_initWithHKey: HKEY_CLASSES_ROOT close: false] autorelease]; |
︙ | ︙ | |||
67 68 69 70 71 72 73 | + (instancetype)usersKey { return [[[self alloc] of_initWithHKey: HKEY_USERS close: false] autorelease]; } | | < | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | + (instancetype)usersKey { return [[[self alloc] of_initWithHKey: HKEY_USERS close: false] autorelease]; } - (instancetype)of_initWithHKey: (HKEY)hKey close: (bool)close { self = [super init]; _hKey = hKey; _close = close; return self; |
︙ | ︙ | |||
115 116 117 118 119 120 121 | status = RegOpenKeyExW(_hKey, path.UTF16String, options, securityAndAccessRights, &subKey); else status = RegOpenKeyExA(_hKey, [path cStringWithEncoding: [OFLocale encoding]], options, securityAndAccessRights, &subKey); | | < < < < < < | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | status = RegOpenKeyExW(_hKey, path.UTF16String, options, securityAndAccessRights, &subKey); else status = RegOpenKeyExA(_hKey, [path cStringWithEncoding: [OFLocale encoding]], options, securityAndAccessRights, &subKey); if (status != ERROR_SUCCESS) @throw [OFOpenWindowsRegistryKeyFailedException exceptionWithRegistryKey: self path: path options: options securityAndAccessRights: securityAndAccessRights status: status]; objc_autoreleasePoolPop(pool); return [[[OFWindowsRegistryKey alloc] of_initWithHKey: subKey close: true] autorelease]; } |
︙ | ︙ | |||
183 184 185 186 187 188 189 | objc_autoreleasePoolPop(pool); return [[[OFWindowsRegistryKey alloc] of_initWithHKey: subKey close: true] autorelease]; } | | < | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | objc_autoreleasePoolPop(pool); return [[[OFWindowsRegistryKey alloc] of_initWithHKey: subKey close: true] autorelease]; } - (OFData *)dataForValueNamed: (OFString *)name type: (DWORD *)type { void *pool = objc_autoreleasePoolPush(); BYTE stackBuffer[256], *buffer = stackBuffer; DWORD length = sizeof(stackBuffer); OFMutableData *ret = nil; bool winNT = [OFSystemInfo isWindowsNT]; LSTATUS status; for (;;) { if (winNT) status = RegQueryValueExW(_hKey, name.UTF16String, NULL, type, buffer, &length); else status = RegQueryValueExA(_hKey, [name cStringWithEncoding: [OFLocale encoding]], NULL, type, buffer, &length); switch (status) { case ERROR_SUCCESS: if (buffer == stackBuffer) { objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
233 234 235 236 237 238 239 | [ret increaseCountBy: length]; buffer = ret.mutableItems; continue; default: @throw [OFGetWindowsRegistryValueFailedException exceptionWithRegistryKey: self | | | | | | | | < | < | < | | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | [ret increaseCountBy: length]; buffer = ret.mutableItems; continue; default: @throw [OFGetWindowsRegistryValueFailedException exceptionWithRegistryKey: self valueName: name status: status]; } } } - (void)setData: (OFData *)data forValueNamed: (OFString *)name type: (DWORD)type { size_t length = data.count * data.itemSize; LSTATUS status; if (length > UINT32_MAX) @throw [OFOutOfRangeException exception]; if ([OFSystemInfo isWindowsNT]) status = RegSetValueExW(_hKey, name.UTF16String, 0, type, data.items, (DWORD)length); else status = RegSetValueExA(_hKey, [name cStringWithEncoding: [OFLocale encoding]], 0, type, data.items, (DWORD)length); if (status != ERROR_SUCCESS) @throw [OFSetWindowsRegistryValueFailedException exceptionWithRegistryKey: self valueName: name data: data type: type status: status]; } - (OFString *)stringForValueNamed: (OFString *)name { return [self stringForValueNamed: name type: NULL]; } - (OFString *)stringForValueNamed: (OFString *)name type: (DWORD *)typeOut { void *pool = objc_autoreleasePoolPush(); DWORD type; OFData *data = [self dataForValueNamed: name type: &type]; OFString *ret; if (data == nil) return nil; if (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_LINK) @throw [OFInvalidEncodingException exception]; if (data.itemSize != 1) @throw [OFInvalidFormatException exception]; if ([OFSystemInfo isWindowsNT]) { const OFChar16 *UTF16String = data.items; size_t length = data.count; if (length % 2 == 1) @throw [OFInvalidFormatException exception]; length /= 2; |
︙ | ︙ | |||
340 341 342 343 344 345 346 | *typeOut = type; objc_autoreleasePoolPop(pool); return [ret autorelease]; } | | < | < < | < | > | | > | > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 | *typeOut = type; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (void)setString: (OFString *)string forValueNamed: (OFString *)name { [self setString: string forValueNamed: name type: REG_SZ]; } - (void)setString: (OFString *)string forValueNamed: (OFString *)name type: (DWORD)type { void *pool = objc_autoreleasePoolPush(); OFData *data; if ([OFSystemInfo isWindowsNT]) data = [OFData dataWithItems: string.UTF16String count: string.UTF16StringLength + 1 itemSize: sizeof(OFChar16)]; else { OFStringEncoding encoding = [OFLocale encoding]; const char *cString = [string cStringWithEncoding: encoding]; size_t length = [string cStringLengthWithEncoding: encoding]; data = [OFData dataWithItems: cString count: length + 1]; } [self setData: data forValueNamed: name type: type]; objc_autoreleasePoolPop(pool); } - (uint32_t)DWORDForValueNamed: (OFString *)name { void *pool = objc_autoreleasePoolPush(); DWORD type, ret; OFData *data = [self dataForValueNamed: name type: &type]; if (data == nil) @throw [OFUndefinedKeyException exceptionWithObject: self key: name value: nil]; if (type != REG_DWORD) @throw [OFInvalidEncodingException exception]; if (data.count != sizeof(ret) || data.itemSize != 1) @throw [OFInvalidFormatException exception]; memcpy(&ret, data.items, sizeof(ret)); objc_autoreleasePoolPop(pool); return ret; } - (void)setDWORD: (uint32_t)dword forValueNamed: (OFString *)name { void *pool = objc_autoreleasePoolPush(); OFData *data = [OFData dataWithItems: &dword count: sizeof(dword)]; [self setData: data forValueNamed: name type: REG_DWORD]; objc_autoreleasePoolPop(pool); } - (uint64_t)QWORDForValueNamed: (OFString *)name { void *pool = objc_autoreleasePoolPush(); DWORD type; uint64_t ret; OFData *data = [self dataForValueNamed: name type: &type]; if (data == nil) @throw [OFUndefinedKeyException exceptionWithObject: self key: name value: nil]; if (type != REG_QWORD) @throw [OFInvalidEncodingException exception]; if (data.count != sizeof(ret) || data.itemSize != 1) @throw [OFInvalidFormatException exception]; memcpy(&ret, data.items, sizeof(ret)); objc_autoreleasePoolPop(pool); return ret; } - (void)setQWORD: (uint64_t)qword forValueNamed: (OFString *)name { void *pool = objc_autoreleasePoolPush(); OFData *data = [OFData dataWithItems: &qword count: sizeof(qword)]; [self setData: data forValueNamed: name type: REG_QWORD]; objc_autoreleasePoolPop(pool); } - (void)deleteValueNamed: (OFString *)name { void *pool = objc_autoreleasePoolPush(); LSTATUS status; if ([OFSystemInfo isWindowsNT]) status = RegDeleteValueW(_hKey, name.UTF16String); else status = RegDeleteValueA(_hKey, [name cStringWithEncoding: [OFLocale encoding]]); if (status != ERROR_SUCCESS) @throw [OFDeleteWindowsRegistryValueFailedException exceptionWithRegistryKey: self valueName: name status: status]; objc_autoreleasePoolPop(pool); } - (void)deleteSubkeyAtPath: (OFString *)subkeyPath { |
︙ | ︙ |
Modified src/OFXMLAttribute.h from [d76aef65ee] to [facd4b4e2b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
44 45 46 47 48 49 50 | /** * @brief The namespace of the attribute. */ #ifndef __cplusplus @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *namespace; #else @property OF_NULLABLE_PROPERTY (readonly, nonatomic, getter=namespace) | | | | | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | /** * @brief The namespace of the attribute. */ #ifndef __cplusplus @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *namespace; #else @property OF_NULLABLE_PROPERTY (readonly, nonatomic, getter=namespace) OFString *nameSpace; #endif /** * @brief Creates a new XML attribute. * * @param name The name of the attribute * @param stringValue The string value of the attribute * @return A new autoreleased OFXMLAttribute with the specified parameters */ + (instancetype)attributeWithName: (OFString *)name stringValue: (OFString *)stringValue; /** * @brief Creates a new XML attribute. * * @param name The name of the attribute * @param nameSpace The namespace of the attribute * @param stringValue The string value of the attribute * @return A new autoreleased OFXMLAttribute with the specified parameters */ + (instancetype)attributeWithName: (OFString *)name namespace: (nullable OFString *)nameSpace stringValue: (OFString *)stringValue; /** * @brief Initializes an already allocated OFXMLAttribute. * * @param name The name of the attribute * @param stringValue The string value of the attribute * @return An initialized OFXMLAttribute with the specified parameters */ - (instancetype)initWithName: (OFString *)name stringValue: (OFString *)stringValue; /** * @brief Initializes an already allocated OFXMLAttribute. * * @param name The name of the attribute * @param nameSpace The namespace of the attribute * @param stringValue The string value of the attribute * @return An initialized OFXMLAttribute with the specified parameters */ - (instancetype)initWithName: (OFString *)name namespace: (nullable OFString *)nameSpace stringValue: (OFString *)stringValue; - (instancetype)initWithSerialization: (OFXMLElement *)element; @end OF_ASSUME_NONNULL_END |
Modified src/OFXMLAttribute.m from [182fa6d94f] to [f2a6cbc394].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
74 75 76 77 78 79 80 | { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || | | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; _name = [[element attributeForName: @"name"].stringValue copy]; _namespace = [[element attributeForName: @"namespace"] .stringValue copy]; _stringValue = [[element attributeForName: @"stringValue"] .stringValue copy]; |
︙ | ︙ | |||
138 139 140 141 142 143 144 | return false; return true; } - (unsigned long)hash { | | | | | | | | < | < | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddHash(&hash, _namespace.hash); OFHashAddHash(&hash, _stringValue.hash); OFHashFinalize(&hash); return hash; } - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS]; [element addAttributeWithName: @"name" stringValue: _name]; if (_namespace != nil) [element addAttributeWithName: @"namespace" stringValue: _namespace]; [element addAttributeWithName: @"stringValue" stringValue: _stringValue]; |
︙ | ︙ |
Modified src/OFXMLCDATA.h from [5fd6a953ec] to [566e9353f4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFXMLCDATA.m from [bc1aa40b4f] to [53038bdcd2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
48 49 50 51 52 53 54 | { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; _CDATA = [element.stringValue copy]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; |
︙ | ︙ | |||
120 121 122 123 124 125 126 | - (OFString *)XMLStringWithIndentation: (unsigned int)indentation { return self.XMLString; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation | | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | - (OFString *)XMLStringWithIndentation: (unsigned int)indentation { return self.XMLString; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation level: (unsigned int)level { return self.XMLString; } - (OFString *)description { return self.XMLString; } - (OFXMLElement *)XMLElementBySerializing { OFXMLElement *element = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS]; [element addChild: self]; return element; } @end |
Modified src/OFXMLCharacters.h from [9150bc53a5] to [314ee7db3d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFXMLCharacters.m from [a2bb78c19c] to [9ea4b56013].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
48 49 50 51 52 53 54 | { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; _characters = [element.stringValue copy]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; |
︙ | ︙ | |||
125 126 127 128 129 130 131 | { return _characters.stringByXMLEscaping; } - (OFXMLElement *)XMLElementBySerializing { return [OFXMLElement elementWithName: self.className | | | 123 124 125 126 127 128 129 130 131 132 133 | { return _characters.stringByXMLEscaping; } - (OFXMLElement *)XMLElementBySerializing { return [OFXMLElement elementWithName: self.className namespace: OFSerializationNS stringValue: _characters]; } @end |
Modified src/OFXMLComment.h from [ca8a1afadc] to [cf96f4e7b5].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | /** * @class OFXMLComment OFXMLComment.h ObjFW/OFXMLComment.h * * @brief A class for representing XML comments. */ @interface OFXMLComment: OFXMLNode { | | > > > > > | | | | | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | /** * @class OFXMLComment OFXMLComment.h ObjFW/OFXMLComment.h * * @brief A class for representing XML comments. */ @interface OFXMLComment: OFXMLNode { OFString *_text; OF_RESERVE_IVARS(OFXMLComment, 4) } /** * @brief The comment text. */ @property (readonly, nonatomic) OFString *text; /** * @brief Creates a new OFXMLComment with the specified text. * * @param text The text for the comment * @return A new OFXMLComment */ + (instancetype)commentWithText: (OFString *)text; /** * @brief Initializes an already allocated OFXMLComment with the specified * text. * * @param text The text for the comment * @return An initialized OFXMLComment */ - (instancetype)initWithText: (OFString *)text; - (instancetype)initWithSerialization: (OFXMLElement *)element; @end OF_ASSUME_NONNULL_END |
Modified src/OFXMLComment.m from [cfed32bae5] to [842e736751].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | #import "OFXMLNode+Private.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFInvalidArgumentException.h" @implementation OFXMLComment | > > | | | | | | | | | | | < | | < | | | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | #import "OFXMLNode+Private.h" #import "OFString.h" #import "OFXMLElement.h" #import "OFInvalidArgumentException.h" @implementation OFXMLComment @synthesize text = _text; + (instancetype)commentWithText: (OFString *)text { return [[[self alloc] initWithText: text] autorelease]; } - (instancetype)initWithText: (OFString *)text { self = [super of_init]; @try { _text = [text copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; _text = [element.stringValue copy]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_text release]; [super dealloc]; } - (bool)isEqual: (id)object { OFXMLComment *comment; if (object == self) return true; if (![object isKindOfClass: [OFXMLComment class]]) return false; comment = object; return ([comment->_text isEqual: _text]); } - (unsigned long)hash { return _text.hash; } - (OFString *)stringValue { return @""; } - (OFString *)XMLString { return [OFString stringWithFormat: @"<!--%@-->", _text]; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation { return [OFString stringWithFormat: @"<!--%@-->", _text]; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation level: (unsigned int)level { OFString *ret; if (indentation > 0 && level > 0) { char *whitespaces = OFAllocMemory((level * indentation) + 1, 1); memset(whitespaces, ' ', level * indentation); whitespaces[level * indentation] = 0; @try { ret = [OFString stringWithFormat: @"%s<!--%@-->", whitespaces, _text]; } @finally { OFFreeMemory(whitespaces); } } else ret = [OFString stringWithFormat: @"<!--%@-->", _text]; return ret; } - (OFString *)description { return [OFString stringWithFormat: @"<!--%@-->", _text]; } - (OFXMLElement *)XMLElementBySerializing { return [OFXMLElement elementWithName: self.className namespace: OFSerializationNS stringValue: _text]; } @end |
Modified src/OFXMLElement+Serialization.h from [a15c443f2f] to [fdd03ade73].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFXMLElement+Serialization.m from [22e42fb0f7] to [c71645309e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | - (id)objectByDeserializing { void *pool = objc_autoreleasePoolPush(); Class class; id object; if ((class = objc_getClass([_name cStringWithEncoding: | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | - (id)objectByDeserializing { void *pool = objc_autoreleasePoolPush(); Class class; id object; if ((class = objc_getClass([_name cStringWithEncoding: OFStringEncodingASCII])) == Nil) @throw [OFInvalidArgumentException exception]; if (![class conformsToProtocol: @protocol(OFSerialization)]) @throw [OFInvalidArgumentException exception]; object = [[class alloc] initWithSerialization: self]; objc_autoreleasePoolPop(pool); return [object autorelease]; } @end |
Modified src/OFXMLElement.h from [817f97f00f] to [470c1e0790].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableString; @class OFString; @class OFXMLAttribute; /** * @class OFXMLElement OFXMLElement.h ObjFW/OFXMLElement.h * * @brief A class which stores an XML element. | > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); @class OFMutableString; @class OFStream; @class OFString; @class OFXMLAttribute; /** * @class OFXMLElement OFXMLElement.h ObjFW/OFXMLElement.h * * @brief A class which stores an XML element. |
︙ | ︙ | |||
49 50 51 52 53 54 55 | /** * @brief The namespace of the element. */ #ifndef __cplusplus @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *namespace; #else @property OF_NULLABLE_PROPERTY (copy, nonatomic, | | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /** * @brief The namespace of the element. */ #ifndef __cplusplus @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *namespace; #else @property OF_NULLABLE_PROPERTY (copy, nonatomic, getter=namespace, setter=setNamespace:) OFString *nameSpace; #endif /** * @brief The default namespace for the element to be used if there is no * parent. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *defaultNamespace; |
︙ | ︙ | |||
98 99 100 101 102 103 104 | + (instancetype)elementWithName: (OFString *)name stringValue: (nullable OFString *)stringValue; /** * @brief Creates a new XML element with the specified name and namespace. * * @param name The name for the element | | | | | < | | | | < | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | + (instancetype)elementWithName: (OFString *)name stringValue: (nullable OFString *)stringValue; /** * @brief Creates a new XML element with the specified name and namespace. * * @param name The name for the element * @param nameSpace The namespace for the element * @return A new autoreleased OFXMLElement with the specified element name and * namespace */ + (instancetype)elementWithName: (OFString *)name namespace: (nullable OFString *)nameSpace; /** * @brief Creates a new XML element with the specified name, namespace and * string value. * * @param name The name for the element * @param nameSpace The namespace for the element * @param stringValue The value for the element * @return A new autoreleased OFXMLElement with the specified element name, * namespace and value */ + (instancetype)elementWithName: (OFString *)name namespace: (nullable OFString *)nameSpace stringValue: (nullable OFString *)stringValue; /** * @brief Creates a new element with the specified element. * * @param element An OFXMLElement to initialize the OFXMLElement with * @return A new autoreleased OFXMLElement with the contents of the specified * element */ + (instancetype)elementWithElement: (OFXMLElement *)element; /** * @brief Parses the string and returns an OFXMLElement for it. * * @param string The string to parse * @return A new autoreleased OFXMLElement with the contents of the string */ + (instancetype)elementWithXMLString: (OFString *)string; /** * @brief Parses the specified stream and returns an OFXMLElement for it. * * @param stream The stream to parse * @return A new autoreleased OFXMLElement with the contents of the specified * stream */ + (instancetype)elementWithStream: (OFStream *)stream; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFXMLElement with the specified name. * * @param name The name for the element |
︙ | ︙ | |||
174 175 176 177 178 179 180 | stringValue: (nullable OFString *)stringValue; /** * @brief Initializes an already allocated OFXMLElement with the specified name * and namespace. * * @param name The name for the element | | | | | | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | stringValue: (nullable OFString *)stringValue; /** * @brief Initializes an already allocated OFXMLElement with the specified name * and namespace. * * @param name The name for the element * @param nameSpace The namespace for the element * @return An initialized OFXMLElement with the specified element name and * namespace */ - (instancetype)initWithName: (OFString *)name namespace: (nullable OFString *)nameSpace; /** * @brief Initializes an already allocated OFXMLElement with the specified name, * namespace and value. * * @param name The name for the element * @param nameSpace The namespace for the element * @param stringValue The value for the element * @return An initialized OFXMLElement with the specified element name, * namespace and value */ - (instancetype)initWithName: (OFString *)name namespace: (nullable OFString *)nameSpace stringValue: (nullable OFString *)stringValue; /** * @brief Initializes an already allocated OFXMLElement with the specified * element. * * @param element An OFXMLElement to initialize the OFXMLElement with |
︙ | ︙ | |||
214 215 216 217 218 219 220 | * with it. * * @param string The string to parse * @return An initialized OFXMLElement with the contents of the string */ - (instancetype)initWithXMLString: (OFString *)string; | < | | | | < | | < | | < | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | * with it. * * @param string The string to parse * @return An initialized OFXMLElement with the contents of the string */ - (instancetype)initWithXMLString: (OFString *)string; /** * @brief Parses the specified stream and initializes an already allocated * OFXMLElement with it. * * @param stream The stream to parse * @return An initialized OFXMLElement with the contents of the specified stream */ - (instancetype)initWithStream: (OFStream *)stream; - (instancetype)initWithSerialization: (OFXMLElement *)element; /** * @brief Sets a prefix for a namespace. * * @param prefix The prefix for the namespace * @param nameSpace The namespace for which the prefix is set */ - (void)setPrefix: (OFString *)prefix forNamespace: (OFString *)nameSpace; /** * @brief Binds a prefix for a namespace. * * @param prefix The prefix for the namespace * @param nameSpace The namespace for which the prefix is bound */ - (void)bindPrefix: (OFString *)prefix forNamespace: (OFString *)nameSpace; /** * @brief Adds the specified attribute. * * If an attribute with the same name and namespace already exists, it is not * added. * |
︙ | ︙ | |||
275 276 277 278 279 280 281 | * @brief Adds the specified attribute with the specified namespace and string * value. * * If an attribute with the same name and namespace already exists, it is not * added. * * @param name The name of the attribute | | | | 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | * @brief Adds the specified attribute with the specified namespace and string * value. * * If an attribute with the same name and namespace already exists, it is not * added. * * @param name The name of the attribute * @param nameSpace The namespace of the attribute * @param stringValue The value of the attribute */ - (void)addAttributeWithName: (OFString *)name namespace: (nullable OFString *)nameSpace stringValue: (OFString *)stringValue; /** * @brief Returns the attribute with the specified name. * * @param attributeName The name of the attribute * @return The attribute with the specified name |
︙ | ︙ | |||
329 330 331 332 333 334 335 | /** * @brief Inserts a child at the specified index. * * @param child An OFXMLNode which is added as a child * @param index The index where the child is added */ | | < | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | /** * @brief Inserts a child at the specified index. * * @param child An OFXMLNode which is added as a child * @param index The index where the child is added */ - (void)insertChild: (OFXMLNode *)child atIndex: (size_t)index; /** * @brief Inserts the specified children at the specified index. * * @param children An array of OFXMLNodes which are added as children * @param index The index where the child is added */ |
︙ | ︙ | |||
362 363 364 365 366 367 368 | /** * @brief Replaces the first child that is equal to the specified OFXMLNode * with the specified node. * * @param child The child to replace * @param node The node to replace the child with */ | | < | < | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | /** * @brief Replaces the first child that is equal to the specified OFXMLNode * with the specified node. * * @param child The child to replace * @param node The node to replace the child with */ - (void)replaceChild: (OFXMLNode *)child withNode: (OFXMLNode *)node; /** * @brief Replaces the child at the specified index with the specified node. * * @param index The index of the child to replace * @param node The node to replace the child with */ - (void)replaceChildAtIndex: (size_t)index withNode: (OFXMLNode *)node; /** * @brief Returns all children that have the specified namespace. * * @return All children that have the specified namespace */ - (OFArray OF_GENERIC(OFXMLElement *) *)elementsForNamespace: |
︙ | ︙ |
Modified src/OFXMLElement.m from [804319c0a1] to [5df92b5be9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | #include <stdlib.h> #include <string.h> #include <assert.h> #import "OFXMLElement.h" | | | | | | > | | | < < < | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #include <stdlib.h> #include <string.h> #include <assert.h> #import "OFXMLElement.h" #import "OFArray.h" #import "OFData.h" #import "OFDictionary.h" #import "OFStream.h" #import "OFString.h" #import "OFXMLAttribute.h" #import "OFXMLCDATA.h" #import "OFXMLCharacters.h" #import "OFXMLElementBuilder.h" #import "OFXMLNode+Private.h" #import "OFXMLParser.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFMalformedXMLException.h" #import "OFUnboundNamespaceException.h" /* References for static linking */ void _references_to_categories_of_OFXMLElement(void) { _OFXMLElement_Serialization_reference = 1; } @interface OFXMLElementElementBuilderDelegate: OFObject <OFXMLElementBuilderDelegate> { @public OFXMLElement *_element; } @end |
︙ | ︙ | |||
75 76 77 78 79 80 81 | } @end @implementation OFXMLElement @synthesize name = _name, namespace = _namespace; @synthesize defaultNamespace = _defaultNamespace; | < < < < < < < < | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | } @end @implementation OFXMLElement @synthesize name = _name, namespace = _namespace; @synthesize defaultNamespace = _defaultNamespace; + (instancetype)elementWithName: (OFString *)name { return [[[self alloc] initWithName: name] autorelease]; } + (instancetype)elementWithName: (OFString *)name stringValue: (OFString *)stringValue |
︙ | ︙ | |||
121 122 123 124 125 126 127 | } + (instancetype)elementWithXMLString: (OFString *)string { return [[[self alloc] initWithXMLString: string] autorelease]; } | < | | < | < < | < < | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | } + (instancetype)elementWithXMLString: (OFString *)string { return [[[self alloc] initWithXMLString: string] autorelease]; } + (instancetype)elementWithStream: (OFStream *)stream { return [[[self alloc] initWithStream: stream] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithName: (OFString *)name { return [self initWithName: name namespace: nil stringValue: nil]; } - (instancetype)initWithName: (OFString *)name stringValue: (OFString *)stringValue { return [self initWithName: name namespace: nil stringValue: stringValue]; } - (instancetype)initWithName: (OFString *)name namespace: (OFString *)namespace { return [self initWithName: name namespace: namespace stringValue: nil]; } - (instancetype)initWithName: (OFString *)name namespace: (OFString *)namespace stringValue: (OFString *)stringValue { self = [super of_init]; |
︙ | ︙ | |||
222 223 224 225 226 227 228 | if (string == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); parser = [OFXMLParser parser]; | | < | | | < | | | | | | | | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | if (string == nil) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); parser = [OFXMLParser parser]; builder = [OFXMLElementBuilder builder]; delegate = [[[OFXMLElementElementBuilderDelegate alloc] init] autorelease]; parser.delegate = builder; builder.delegate = delegate; [parser parseString: string]; if (!parser.hasFinishedParsing) @throw [OFMalformedXMLException exceptionWithParser: parser]; self = [delegate->_element retain]; objc_autoreleasePoolPop(pool); return self; } - (instancetype)initWithStream: (OFStream *)stream { void *pool; OFXMLParser *parser; OFXMLElementBuilder *builder; OFXMLElementElementBuilderDelegate *delegate; [self release]; pool = objc_autoreleasePoolPush(); parser = [OFXMLParser parser]; builder = [OFXMLElementBuilder builder]; delegate = [[[OFXMLElementElementBuilderDelegate alloc] init] autorelease]; parser.delegate = builder; builder.delegate = delegate; [parser parseStream: stream]; if (!parser.hasFinishedParsing) @throw [OFMalformedXMLException exceptionWithParser: parser]; self = [delegate->_element retain]; objc_autoreleasePoolPop(pool); return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { self = [super of_init]; @try { void *pool = objc_autoreleasePoolPush(); OFXMLElement *attributesElement, *namespacesElement; OFXMLElement *childrenElement; OFEnumerator *keyEnumerator, *objectEnumerator; OFString *key, *object; if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; _name = [[element attributeForName: @"name"].stringValue copy]; _namespace = [[element attributeForName: @"namespace"] .stringValue copy]; _defaultNamespace = [[element attributeForName: @"defaultNamespace"].stringValue copy]; attributesElement = [[element elementForName: @"attributes" namespace: OFSerializationNS] elementsForNamespace: OFSerializationNS].firstObject; namespacesElement = [[element elementForName: @"namespaces" namespace: OFSerializationNS] elementsForNamespace: OFSerializationNS].firstObject; childrenElement = [[element elementForName: @"children" namespace: OFSerializationNS] elementsForNamespace: OFSerializationNS].firstObject; _attributes = [attributesElement.objectByDeserializing mutableCopy]; _namespaces = [namespacesElement.objectByDeserializing mutableCopy]; _children = [childrenElement.objectByDeserializing mutableCopy]; |
︙ | ︙ | |||
422 423 424 425 426 427 428 | [ret makeImmutable]; return ret; } - (OFString *)of_XMLStringWithParent: (OFXMLElement *)parent | | | | | | < | | | | > | | | | | | < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | < | | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | [ret makeImmutable]; return ret; } - (OFString *)of_XMLStringWithParent: (OFXMLElement *)parent namespaces: (OFDictionary *)allNS indentation: (unsigned int)indentation level: (unsigned int)level OF_DIRECT { void *pool; char *cString; size_t length, i; OFString *prefix, *parentPrefix; OFString *ret; OFString *defaultNS; pool = objc_autoreleasePoolPush(); parentPrefix = [allNS objectForKey: (parent != nil && parent->_namespace != nil ? parent->_namespace : (OFString *)@"")]; /* Add the namespaces of the current element */ if (allNS != nil) { OFEnumerator *keyEnumerator = [_namespaces keyEnumerator]; OFEnumerator *objectEnumerator = [_namespaces objectEnumerator]; OFMutableDictionary *tmp; OFString *key, *object; tmp = [[allNS mutableCopy] autorelease]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) [tmp setObject: object forKey: key]; allNS = tmp; } else allNS = _namespaces; prefix = [allNS objectForKey: (_namespace != nil ? _namespace : (OFString *)@"")]; if (parent != nil && parent->_namespace != nil && parentPrefix == nil) defaultNS = parent->_namespace; else if (parent != nil && parent->_defaultNamespace != nil) defaultNS = parent->_defaultNamespace; else defaultNS = _defaultNamespace; i = 0; length = _name.UTF8StringLength + 3 + (level * indentation); cString = OFAllocMemory(length, 1); @try { memset(cString + i, ' ', level * indentation); i += level * indentation; /* Start of tag */ cString[i++] = '<'; if (prefix != nil && ![_namespace isEqual: defaultNS]) { length += prefix.UTF8StringLength + 1; cString = OFResizeMemory(cString, length, 1); memcpy(cString + i, prefix.UTF8String, prefix.UTF8StringLength); i += prefix.UTF8StringLength; cString[i++] = ':'; } memcpy(cString + i, _name.UTF8String, _name.UTF8StringLength); i += _name.UTF8StringLength; /* xmlns if necessary */ if (prefix == nil && ((_namespace != nil && ![_namespace isEqual: defaultNS]) || (_namespace == nil && defaultNS != nil))) { length += _namespace.UTF8StringLength + 9; cString = OFResizeMemory(cString, length, 1); memcpy(cString + i, " xmlns='", 8); i += 8; memcpy(cString + i, _namespace.UTF8String, _namespace.UTF8StringLength); i += _namespace.UTF8StringLength; cString[i++] = '\''; } /* Attributes */ for (OFXMLAttribute *attribute in _attributes) { void *pool2 = objc_autoreleasePoolPush(); const char *attributeNameCString = attribute->_name.UTF8String; size_t attributeNameLength = attribute->_name.UTF8StringLength; OFString *attributePrefix = nil; OFString *tmp = attribute.stringValue.stringByXMLEscaping; char delimiter = (attribute->_useDoubleQuotes ? '"' : '\''); if (attribute->_namespace != nil && (attributePrefix = [allNS objectForKey: attribute->_namespace]) == nil) @throw [OFUnboundNamespaceException exceptionWithNamespace: attribute.namespace element: self]; length += attributeNameLength + (attributePrefix != nil ? attributePrefix.UTF8StringLength + 1 : 0) + tmp.UTF8StringLength + 4; cString = OFResizeMemory(cString, length, 1); cString[i++] = ' '; if (attributePrefix != nil) { memcpy(cString + i, attributePrefix.UTF8String, attributePrefix.UTF8StringLength); i += attributePrefix.UTF8StringLength; cString[i++] = ':'; } memcpy(cString + i, attributeNameCString, attributeNameLength); i += attributeNameLength; cString[i++] = '='; cString[i++] = delimiter; memcpy(cString + i, tmp.UTF8String, tmp.UTF8StringLength); i += tmp.UTF8StringLength; cString[i++] = delimiter; objc_autoreleasePoolPop(pool2); } /* Children */ if (_children != nil) { OFMutableData *tmp = [OFMutableData data]; bool indent; if (indentation > 0) { indent = true; for (OFXMLNode *child in _children) { if ([child isKindOfClass: [OFXMLCharacters class]] || [child isKindOfClass: [OFXMLCDATA class]]) { indent = false; break; } } } else indent = false; for (OFXMLNode *child in _children) { OFString *childString; unsigned int ind = (indent ? indentation : 0); if (ind) [tmp addItem: "\n"]; if ([child isKindOfClass: [OFXMLElement class]]) childString = [(OFXMLElement *)child of_XMLStringWithParent: self namespaces: allNS indentation: ind level: level + 1]; else childString = [child XMLStringWithIndentation: ind level: level + 1]; [tmp addItems: childString.UTF8String count: childString.UTF8StringLength]; } if (indent) [tmp addItem: "\n"]; length += tmp.count + _name.UTF8StringLength + 2 + (indent ? level * indentation : 0); cString = OFResizeMemory(cString, length, 1); cString[i++] = '>'; memcpy(cString + i, tmp.items, tmp.count); i += tmp.count; if (indent) { memset(cString + i, ' ', level * indentation); i += level * indentation; } cString[i++] = '<'; cString[i++] = '/'; if (prefix != nil) { length += prefix.UTF8StringLength + 1; cString = OFResizeMemory(cString, length, 1); memcpy(cString + i, prefix.UTF8String, prefix.UTF8StringLength); i += prefix.UTF8StringLength; cString[i++] = ':'; } memcpy(cString + i, _name.UTF8String, _name.UTF8StringLength); i += _name.UTF8StringLength; } else cString[i++] = '/'; cString[i++] = '>'; assert(i == length); objc_autoreleasePoolPop(pool); ret = [OFString stringWithUTF8String: cString length: length]; } @finally { OFFreeMemory(cString); } return ret; } - (OFString *)XMLString { return [self of_XMLStringWithParent: nil |
︙ | ︙ | |||
692 693 694 695 696 697 698 | - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className | | | < | | | | 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 | - (OFXMLElement *)XMLElementBySerializing { void *pool = objc_autoreleasePoolPush(); OFXMLElement *element; element = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS]; if (_name != nil) [element addAttributeWithName: @"name" stringValue: _name]; if (_namespace != nil) [element addAttributeWithName: @"namespace" stringValue: _namespace]; if (_defaultNamespace != nil) [element addAttributeWithName: @"defaultNamespace" stringValue: _defaultNamespace]; if (_attributes != nil) { OFXMLElement *attributesElement; attributesElement = [OFXMLElement elementWithName: @"attributes" namespace: OFSerializationNS]; [attributesElement addChild: _attributes.XMLElementBySerializing]; [element addChild: attributesElement]; } if (_namespaces != nil) { OFXMLElement *namespacesElement; OFMutableDictionary *namespacesCopy = [[_namespaces mutableCopy] autorelease]; [namespacesCopy removeObjectForKey: @"http://www.w3.org/XML/1998/namespace"]; [namespacesCopy removeObjectForKey: @"http://www.w3.org/2000/xmlns/"]; if (namespacesCopy.count > 0) { namespacesElement = [OFXMLElement elementWithName: @"namespaces" namespace: OFSerializationNS]; [namespacesElement addChild: namespacesCopy.XMLElementBySerializing]; [element addChild: namespacesElement]; } } if (_children != nil) { OFXMLElement *childrenElement; childrenElement = [OFXMLElement elementWithName: @"children" namespace: OFSerializationNS]; [childrenElement addChild: _children.XMLElementBySerializing]; [element addChild: childrenElement]; } [element retain]; objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
850 851 852 853 854 855 856 | [objects[i]->_name isEqual: attributeName]) { [_attributes removeObjectAtIndex: i]; return; } } } | | < | < | < | < | < | < | < | < | < | < | < | < | 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 | [objects[i]->_name isEqual: attributeName]) { [_attributes removeObjectAtIndex: i]; return; } } } - (void)setPrefix: (OFString *)prefix forNamespace: (OFString *)namespace { if (prefix.length == 0) @throw [OFInvalidArgumentException exception]; if (namespace == nil) namespace = @""; [_namespaces setObject: prefix forKey: namespace]; } - (void)bindPrefix: (OFString *)prefix forNamespace: (OFString *)namespace { [self setPrefix: prefix forNamespace: namespace]; [self addAttributeWithName: prefix namespace: @"http://www.w3.org/2000/xmlns/" stringValue: namespace]; } - (void)addChild: (OFXMLNode *)child { if ([child isKindOfClass: [OFXMLAttribute class]]) @throw [OFInvalidArgumentException exception]; if (_children == nil) _children = [[OFMutableArray alloc] init]; [_children addObject: child]; } - (void)insertChild: (OFXMLNode *)child atIndex: (size_t)idx { if ([child isKindOfClass: [OFXMLAttribute class]]) @throw [OFInvalidArgumentException exception]; if (_children == nil) _children = [[OFMutableArray alloc] init]; [_children insertObject: child atIndex: idx]; } - (void)insertChildren: (OFArray *)children atIndex: (size_t)idx { for (OFXMLNode *node in children) if ([node isKindOfClass: [OFXMLAttribute class]]) @throw [OFInvalidArgumentException exception]; [_children insertObjectsFromArray: children atIndex: idx]; } - (void)removeChild: (OFXMLNode *)child { if ([child isKindOfClass: [OFXMLAttribute class]]) @throw [OFInvalidArgumentException exception]; [_children removeObject: child]; } - (void)removeChildAtIndex: (size_t)idx { [_children removeObjectAtIndex: idx]; } - (void)replaceChild: (OFXMLNode *)child withNode: (OFXMLNode *)node { if ([node isKindOfClass: [OFXMLAttribute class]] || [child isKindOfClass: [OFXMLAttribute class]]) @throw [OFInvalidArgumentException exception]; [_children replaceObject: child withObject: node]; } - (void)replaceChildAtIndex: (size_t)idx withNode: (OFXMLNode *)node { if ([node isKindOfClass: [OFXMLAttribute class]]) @throw [OFInvalidArgumentException exception]; [_children replaceObjectAtIndex: idx withObject: node]; } - (OFXMLElement *)elementForName: (OFString *)elementName { return [self elementsForName: elementName].firstObject; } |
︙ | ︙ | |||
1064 1065 1066 1067 1068 1069 1070 | return false; return true; } - (unsigned long)hash { | | | | | | | | | | | 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 | return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _name.hash); OFHashAddHash(&hash, _namespace.hash); OFHashAddHash(&hash, _defaultNamespace.hash); OFHashAddHash(&hash, _attributes.hash); OFHashAddHash(&hash, _namespaces.hash); OFHashAddHash(&hash, _children.hash); OFHashFinalize(&hash); return hash; } - (id)copy { return [[[self class] alloc] initWithElement: self]; } @end |
Modified src/OFXMLElementBuilder.h from [6a04a51f54] to [657f65f42e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
71 72 73 74 75 76 77 | * * If this method is not implemented in the delegate, the default is to throw * an OFMalformedXMLException. * * @param builder The builder which did not expect the close tag * @param name The name of the close tag * @param prefix The prefix of the close tag | | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | * * If this method is not implemented in the delegate, the default is to throw * an OFMalformedXMLException. * * @param builder The builder which did not expect the close tag * @param name The name of the close tag * @param prefix The prefix of the close tag * @param nameSpace The namespace of the close tag */ - (void)elementBuilder: (OFXMLElementBuilder *)builder didNotExpectCloseTag: (OFString *)name prefix: (nullable OFString *)prefix namespace: (nullable OFString *)nameSpace; /** * @brief This callback is called when the XML parser for the element builder * found an unknown entity. * * @param builder The element builder which found an unknown entity * @param entity The name of the entity |
︙ | ︙ | |||
118 119 120 121 122 123 124 | id <OFXMLElementBuilderDelegate> delegate; /** * @brief Creates a new element builder. * * @return A new, autoreleased OFXMLElementBuilder */ | | | 116 117 118 119 120 121 122 123 124 125 126 | id <OFXMLElementBuilderDelegate> delegate; /** * @brief Creates a new element builder. * * @return A new, autoreleased OFXMLElementBuilder */ + (instancetype)builder; @end OF_ASSUME_NONNULL_END |
Modified src/OFXMLElementBuilder.m from [8b8caf6ff6] to [b8984275c9].
1 | /* | < < | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFXMLElementBuilder.h" #import "OFArray.h" #import "OFXMLAttribute.h" #import "OFXMLCDATA.h" #import "OFXMLCharacters.h" #import "OFXMLComment.h" #import "OFXMLElement.h" #import "OFXMLParser.h" #import "OFXMLProcessingInstruction.h" #import "OFMalformedXMLException.h" @implementation OFXMLElementBuilder @synthesize delegate = _delegate; + (instancetype)builder { return [[[self alloc] init] autorelease]; } - (instancetype)init { self = [super init]; |
︙ | ︙ | |||
54 55 56 57 58 59 60 | - (void)dealloc { [_stack release]; [super dealloc]; } | | | > | | > | < | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | - (void)dealloc { [_stack release]; [super dealloc]; } - (void)parser: (OFXMLParser *)parser foundProcessingInstructionWithTarget: (OFString *)target data: (OFString *)data { OFXMLProcessingInstruction *node = [OFXMLProcessingInstruction processingInstructionWithTarget: target data: data]; OFXMLElement *parent = _stack.lastObject; if (parent != nil) [parent addChild: node]; else if ([_delegate respondsToSelector: @selector(elementBuilder:didBuildParentlessNode:)]) [_delegate elementBuilder: self didBuildParentlessNode: node]; } - (void)parser: (OFXMLParser *)parser didStartElement: (OFString *)name prefix: (OFString *)prefix namespace: (OFString *)namespace attributes: (OFArray *)attributes |
︙ | ︙ | |||
134 135 136 137 138 139 140 | node = [OFXMLCharacters charactersWithString: characters]; parent = _stack.lastObject; if (parent != nil) [parent addChild: node]; else if ([_delegate respondsToSelector: @selector(elementBuilder:didBuildParentlessNode:)]) | | < | < | | < | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | node = [OFXMLCharacters charactersWithString: characters]; parent = _stack.lastObject; if (parent != nil) [parent addChild: node]; else if ([_delegate respondsToSelector: @selector(elementBuilder:didBuildParentlessNode:)]) [_delegate elementBuilder: self didBuildParentlessNode: node]; } - (void)parser: (OFXMLParser *)parser foundCDATA: (OFString *)CDATA { OFXMLCDATA *node = [OFXMLCDATA CDATAWithString: CDATA]; OFXMLElement *parent = _stack.lastObject; if (parent != nil) [parent addChild: node]; else if ([_delegate respondsToSelector: @selector(elementBuilder:didBuildParentlessNode:)]) [_delegate elementBuilder: self didBuildParentlessNode: node]; } - (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment { OFXMLComment *node = [OFXMLComment commentWithText: comment]; OFXMLElement *parent = _stack.lastObject; if (parent != nil) [parent addChild: node]; else if ([_delegate respondsToSelector: @selector(elementBuilder:didBuildParentlessNode:)]) [_delegate elementBuilder: self didBuildParentlessNode: node]; } - (OFString *)parser: (OFXMLParser *)parser foundUnknownEntityNamed: (OFString *)entity { if ([_delegate respondsToSelector: @selector(elementBuilder:foundUnknownEntityNamed:)]) return [_delegate elementBuilder: self foundUnknownEntityNamed: entity]; return nil; } @end |
Modified src/OFXMLNode+Private.h from [19f5e39b7a] to [fcadbb17a0].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFXMLNode.h from [ec230c5902] to [506d741d52].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFXMLNode.m from [089c365f8a] to [fd3b7789fd].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
74 75 76 77 78 79 80 | - (double)doubleValue { return self.stringValue.doubleValue; } - (OFString *)XMLString { | | < | < | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | - (double)doubleValue { return self.stringValue.doubleValue; } - (OFString *)XMLString { return [self XMLStringWithIndentation: 0 level: 0]; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation { return [self XMLStringWithIndentation: 0 level: 0]; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation level: (unsigned int)level { OF_UNRECOGNIZED_SELECTOR } - (OFString *)description { return [self XMLStringWithIndentation: 2 level: 0]; } - (OFXMLElement *)XMLElementBySerializing { OF_UNRECOGNIZED_SELECTOR } - (id)copy { return [self retain]; } @end |
Modified src/OFXMLParser.h from [9632092363] to [e4ba7bdb79].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
32 33 34 35 36 37 38 | * @protocol OFXMLParserDelegate OFXMLParser.h ObjFW/OFXMLParser.h * * @brief A protocol that needs to be implemented by delegates for OFXMLParser. */ @protocol OFXMLParserDelegate <OFObject> @optional /** | | | | > | | | > | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | * @protocol OFXMLParserDelegate OFXMLParser.h ObjFW/OFXMLParser.h * * @brief A protocol that needs to be implemented by delegates for OFXMLParser. */ @protocol OFXMLParserDelegate <OFObject> @optional /** * @brief This callback is called when the XML parser found a processing * instruction. * * @param parser The parser which found a processing instruction * @param target The target of the processing instruction * @param data The data of the processing instruction */ - (void)parser: (OFXMLParser *)parser foundProcessingInstructionWithTarget: (OFString *)target data: (OFString *)data; /** * @brief This callback is called when the XML parser found the start of a new * tag. * * @param parser The parser which found a new tag * @param name The name of the tag which just started |
︙ | ︙ | |||
80 81 82 83 84 85 86 | * * In case there are comments or CDATA, it is possible that this callback is * called multiple times in a row. * * @param parser The parser which found a string * @param characters The characters the XML parser found */ | < | | < | < | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | * * In case there are comments or CDATA, it is possible that this callback is * called multiple times in a row. * * @param parser The parser which found a string * @param characters The characters the XML parser found */ - (void)parser: (OFXMLParser *)parser foundCharacters: (OFString *)characters; /** * @brief This callback is called when the XML parser found CDATA. * * @param parser The parser which found a string * @param CDATA The CDATA the XML parser found */ - (void)parser: (OFXMLParser *)parser foundCDATA: (OFString *)CDATA; /** * @brief This callback is called when the XML parser found a comment. * * @param parser The parser which found a comment * @param comment The comment the XML parser found */ - (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment; /** * @brief This callback is called when the XML parser found an entity it * doesn't know. * * The callback is supposed to return a substitution for the entity or `nil` if * it is not known to the callback as well, in which case an exception will be |
︙ | ︙ | |||
129 130 131 132 133 134 135 | * OFXMLParser is an event-based XML parser which calls the delegate's callbacks * as soon as it finds something, thus suitable for streams as well. */ OF_SUBCLASSING_RESTRICTED @interface OFXMLParser: OFObject { id <OFXMLParserDelegate> _Nullable _delegate; | < < < < < < < < < < < < < < < < < < < < < | | | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | * OFXMLParser is an event-based XML parser which calls the delegate's callbacks * as soon as it finds something, thus suitable for streams as well. */ OF_SUBCLASSING_RESTRICTED @interface OFXMLParser: OFObject { id <OFXMLParserDelegate> _Nullable _delegate; uint_least8_t _state; size_t _i, _last; const char *_Nullable _data; OFMutableData *_buffer; OFString *_Nullable _name, *_Nullable _prefix; OFMutableArray OF_GENERIC(OFMutableDictionary OF_GENERIC(OFString *, OFString *) *) *_namespaces; OFMutableArray OF_GENERIC(OFXMLAttribute *) *_attributes; OFString *_Nullable _attributeName, *_Nullable _attributePrefix; char _delimiter; OFMutableArray OF_GENERIC(OFString *) *_previous; size_t _level; bool _acceptProlog; size_t _lineNumber; bool _lastCarriageReturn, _finishedParsing; OFStringEncoding _encoding; size_t _depthLimit; } /** * @brief The delegate that is used by the XML parser. */ @property OF_NULLABLE_PROPERTY (assign, nonatomic) id <OFXMLParserDelegate> delegate; /** * @brief The current line number. */ @property (readonly, nonatomic) size_t lineNumber; /** * @brief Whether the XML parser has finished parsing. */ @property (readonly, nonatomic, getter=hasFinishedParsing) bool finishedParsing; /** * @brief The depth limit for the XML parser. * * If the depth limit is exceeded, an OFMalformedXMLException is thrown. * * The default is 32. 0 means unlimited (insecure!). |
︙ | ︙ | |||
208 209 210 211 212 213 214 | /** * @brief Parses the specified buffer with the specified size. * * @param buffer The buffer to parse * @param length The length of the buffer */ | | < < < < < < < < < < | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | /** * @brief Parses the specified buffer with the specified size. * * @param buffer The buffer to parse * @param length The length of the buffer */ - (void)parseBuffer: (const char *)buffer length: (size_t)length; /** * @brief Parses the specified string. * * @param string The string to parse */ - (void)parseString: (OFString *)string; /** * @brief Parses the specified stream. * * @param stream The stream to parse */ - (void)parseStream: (OFStream *)stream; @end OF_ASSUME_NONNULL_END |
Modified src/OFXMLParser.m from [ff15f62058] to [beb767fa68].
1 | /* | < < | | | < < | > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | < | | | | | < | < | | | | | | | | | | | | | | < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #define OF_XML_PARSER_M #include <string.h> #import "OFXMLParser.h" #import "OFArray.h" #import "OFCharacterSet.h" #import "OFData.h" #import "OFDictionary.h" #ifdef OF_HAVE_FILES # import "OFFile.h" #endif #import "OFStream.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFXMLAttribute.h" #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFMalformedXMLException.h" #import "OFOutOfRangeException.h" #import "OFUnboundPrefixException.h" enum { stateInByteOrderMark, stateOutsideTag, stateTagOpened, stateInProcessingInstruction, stateInTagName, stateInCloseTagName, stateInTag, stateInAttributeName, stateExpectAttributeEqualSign, stateExpectAttributeDelimiter, stateInAttributeValue, stateExpectTagClose, stateExpectSpaceOrTagClose, stateInExclamationMark, stateInCDATAOpening, stateInCDATA, stateInCommentOpening, stateInComment1, stateInComment2, stateInDOCTYPE }; @interface OFXMLParser () <OFStringXMLUnescapingDelegate> @end static void inByteOrderMarkState(OFXMLParser *); static void outsideTagState(OFXMLParser *); static void tagOpenedState(OFXMLParser *); static void inProcessingInstructionState(OFXMLParser *); static void inTagNameState(OFXMLParser *); static void inCloseTagNameState(OFXMLParser *); static void inTagState(OFXMLParser *); static void inAttributeNameState(OFXMLParser *); static void expectAttributeEqualSignState(OFXMLParser *); static void expectAttributeDelimiterState(OFXMLParser *); static void inAttributeValueState(OFXMLParser *); static void expectTagCloseState(OFXMLParser *); static void expectSpaceOrTagCloseState(OFXMLParser *); static void inExclamationMarkState(OFXMLParser *); static void inCDATAOpeningState(OFXMLParser *); static void inCDATAState(OFXMLParser *); static void inCommentOpeningState(OFXMLParser *); static void inCommentState1(OFXMLParser *); static void inCommentState2(OFXMLParser *); static void inDOCTYPEState(OFXMLParser *); typedef void (*StateFunction)(OFXMLParser *); static StateFunction lookupTable[] = { [stateInByteOrderMark] = inByteOrderMarkState, [stateOutsideTag] = outsideTagState, [stateTagOpened] = tagOpenedState, [stateInProcessingInstruction] = inProcessingInstructionState, [stateInTagName] = inTagNameState, [stateInCloseTagName] = inCloseTagNameState, [stateInTag] = inTagState, [stateInAttributeName] = inAttributeNameState, [stateExpectAttributeEqualSign] = expectAttributeEqualSignState, [stateExpectAttributeDelimiter] = expectAttributeDelimiterState, [stateInAttributeValue] = inAttributeValueState, [stateExpectTagClose] = expectTagCloseState, [stateExpectSpaceOrTagClose] = expectSpaceOrTagCloseState, [stateInExclamationMark] = inExclamationMarkState, [stateInCDATAOpening] = inCDATAOpeningState, [stateInCDATA] = inCDATAState, [stateInCommentOpening] = inCommentOpeningState, [stateInComment1] = inCommentState1, [stateInComment2] = inCommentState2, [stateInDOCTYPE] = inDOCTYPEState }; static OF_INLINE void appendToBuffer(OFMutableData *buffer, const char *string, OFStringEncoding encoding, size_t length) { if OF_LIKELY(encoding == OFStringEncodingUTF8) [buffer addItems: string count: length]; else { void *pool = objc_autoreleasePoolPush(); OFString *tmp = [OFString stringWithCString: string encoding: encoding length: length]; [buffer addItems: tmp.UTF8String count: tmp.UTF8StringLength]; objc_autoreleasePoolPop(pool); } } static OFString * transformString(OFXMLParser *parser, OFMutableData *buffer, size_t cut, bool unescape) |
︙ | ︙ | |||
128 129 130 131 132 133 134 | length--; } else items[i] = '\n'; } else if (items[i] == '&') hasEntities = true; } | | < | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | length--; } else items[i] = '\n'; } else if (items[i] == '&') hasEntities = true; } ret = [OFString stringWithUTF8String: items length: length]; if (unescape && hasEntities) { @try { return [ret stringByXMLUnescapingWithDelegate: parser]; } @catch (OFInvalidFormatException *e) { @throw [OFMalformedXMLException exceptionWithParser: parser]; |
︙ | ︙ | |||
212 213 214 215 216 217 218 | dict = [OFMutableDictionary dictionaryWithKeysAndObjects: @"xml", @"http://www.w3.org/XML/1998/namespace", @"xmlns", @"http://www.w3.org/2000/xmlns/", nil]; [_namespaces addObject: dict]; _acceptProlog = true; _lineNumber = 1; | | | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | dict = [OFMutableDictionary dictionaryWithKeysAndObjects: @"xml", @"http://www.w3.org/XML/1998/namespace", @"xmlns", @"http://www.w3.org/2000/xmlns/", nil]; [_namespaces addObject: dict]; _acceptProlog = true; _lineNumber = 1; _encoding = OFStringEncodingUTF8; _depthLimit = 32; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
238 239 240 241 242 243 244 | [_attributeName release]; [_attributePrefix release]; [_previous release]; [super dealloc]; } | | < | | | < | < | < | < < < < < < < < < < < < < | | | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | [_attributeName release]; [_attributePrefix release]; [_previous release]; [super dealloc]; } - (void)parseBuffer: (const char *)buffer length: (size_t)length { _data = buffer; for (_i = _last = 0; _i < length; _i++) { size_t j = _i; lookupTable[_state](self); /* Ensure we don't count this character twice */ if (_i != j) continue; if (_data[_i] == '\r' || (_data[_i] == '\n' && !_lastCarriageReturn)) _lineNumber++; _lastCarriageReturn = (_data[_i] == '\r'); } /* In stateInTag, there can be only spaces */ if (length - _last > 0 && _state != stateInTag) appendToBuffer(_buffer, _data + _last, _encoding, length - _last); } - (void)parseString: (OFString *)string { [self parseBuffer: string.UTF8String length: string.UTF8StringLength]; } - (void)parseStream: (OFStream *)stream { size_t pageSize = [OFSystemInfo pageSize]; char *buffer = OFAllocMemory(1, pageSize); @try { while (!stream.atEndOfStream) { size_t length = [stream readIntoBuffer: buffer length: pageSize]; [self parseBuffer: buffer length: length]; } } @finally { OFFreeMemory(buffer); } } static void inByteOrderMarkState(OFXMLParser *self) { if (self->_data[self->_i] != "\xEF\xBB\xBF"[self->_level]) { if (self->_level == 0) { self->_state = stateOutsideTag; self->_i--; return; } @throw [OFMalformedXMLException exceptionWithParser: self]; } if (self->_level++ == 2) self->_state = stateOutsideTag; self->_last = self->_i + 1; } /* Not in a tag */ static void outsideTagState(OFXMLParser *self) |
︙ | ︙ | |||
356 357 358 359 360 361 362 | objc_autoreleasePoolPop(pool); } [self->_buffer removeAllItems]; self->_last = self->_i + 1; | | | | | | | < < < | | | 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 | objc_autoreleasePoolPop(pool); } [self->_buffer removeAllItems]; self->_last = self->_i + 1; self->_state = stateTagOpened; } /* Tag was just opened */ static void tagOpenedState(OFXMLParser *self) { if (self->_finishedParsing && self->_data[self->_i] != '!' && self->_data[self->_i] != '?') @throw [OFMalformedXMLException exceptionWithParser: self]; switch (self->_data[self->_i]) { case '?': self->_last = self->_i + 1; self->_state = stateInProcessingInstruction; self->_level = 0; break; case '/': self->_last = self->_i + 1; self->_state = stateInCloseTagName; self->_acceptProlog = false; break; case '!': self->_last = self->_i + 1; self->_state = stateInExclamationMark; self->_acceptProlog = false; break; default: if (self->_depthLimit > 0 && self->_previous.count >= self->_depthLimit) @throw [OFOutOfRangeException exception]; self->_state = stateInTagName; self->_acceptProlog = false; self->_i--; break; } } /* <?xml […]?> */ static bool parseXMLProcessingInstruction(OFXMLParser *self, OFString *data) { const char *cString; size_t length, last; int PIState = 0; OFString *attribute = nil; OFMutableString *value = nil; char piDelimiter = 0; bool hasVersion = false; if (!self->_acceptProlog) return false; self->_acceptProlog = false; cString = data.UTF8String; length = data.UTF8StringLength; last = 0; for (size_t i = 0; i < length; i++) { switch (PIState) { case 0: if (cString[i] == ' ' || cString[i] == '\t' || cString[i] == '\r' || cString[i] == '\n') |
︙ | ︙ | |||
471 472 473 474 475 476 477 | hasVersion = true; } if ([attribute isEqual: @"encoding"]) { @try { self->_encoding = | | | | | > > > > > > > > > | > > > > | | | | | | | > | | 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 | hasVersion = true; } if ([attribute isEqual: @"encoding"]) { @try { self->_encoding = OFStringEncodingParseName(value); } @catch (OFInvalidArgumentException *e) { @throw [OFInvalidEncodingException exception]; } } last = i + 1; PIState = 0; break; } } if (PIState != 0 || !hasVersion) return false; return true; } /* Inside processing instruction */ static void inProcessingInstructionState(OFXMLParser *self) { if (self->_data[self->_i] == '?') self->_level = 1; else if (self->_level == 1 && self->_data[self->_i] == '>') { void *pool = objc_autoreleasePoolPush(); OFString *PI, *target, *data = nil; OFCharacterSet *whitespaceCS; size_t pos; appendToBuffer(self->_buffer, self->_data + self->_last, self->_encoding, self->_i - self->_last); PI = transformString(self, self->_buffer, 1, false); whitespaceCS = [OFCharacterSet characterSetWithCharactersInString: @" \r\n\r"]; pos = [PI indexOfCharacterFromSet: whitespaceCS]; if (pos != OFNotFound) { target = [PI substringToIndex: pos]; data = [[PI substringFromIndex: pos + 1] stringByDeletingEnclosingWhitespaces]; if (data.length == 0) data = nil; } else target = PI; if ([target caseInsensitiveCompare: @"xml"] == OFOrderedSame) if (!parseXMLProcessingInstruction(self, data)) @throw [OFMalformedXMLException exceptionWithParser: self]; if ([self->_delegate respondsToSelector: @selector( parser:foundProcessingInstructionWithTarget:data:)]) [self->_delegate parser: self foundProcessingInstructionWithTarget: target data: data]; objc_autoreleasePoolPop(pool); [self->_buffer removeAllItems]; self->_last = self->_i + 1; self->_state = stateOutsideTag; } else self->_level = 0; } /* Inside a tag, no name yet */ static void inTagNameState(OFXMLParser *self) |
︙ | ︙ | |||
566 567 568 569 570 571 572 | length: tmp - bufferCString]; } else { self->_name = [bufferString copy]; self->_prefix = nil; } if (self->_data[self->_i] == '>' || self->_data[self->_i] == '/') { | < < | | 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | length: tmp - bufferCString]; } else { self->_name = [bufferString copy]; self->_prefix = nil; } if (self->_data[self->_i] == '>' || self->_data[self->_i] == '/') { OFString *namespace = namespaceForPrefix(self->_prefix, self->_namespaces); if (self->_prefix != nil && namespace == nil) @throw [OFUnboundPrefixException exceptionWithPrefix: self->_prefix parser: self]; |
︙ | ︙ | |||
602 603 604 605 606 607 608 | [self->_previous addObject: bufferString]; [self->_name release]; [self->_prefix release]; self->_name = self->_prefix = nil; self->_state = (self->_data[self->_i] == '/' | | < | | 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 | [self->_previous addObject: bufferString]; [self->_name release]; [self->_prefix release]; self->_name = self->_prefix = nil; self->_state = (self->_data[self->_i] == '/' ? stateExpectTagClose : stateOutsideTag); } else self->_state = stateInTag; if (self->_data[self->_i] != '/') [self->_namespaces addObject: [OFMutableDictionary dictionary]]; objc_autoreleasePoolPop(pool); [self->_buffer removeAllItems]; |
︙ | ︙ | |||
683 684 685 686 687 688 689 | [self->_namespaces removeLastObject]; [self->_name release]; [self->_prefix release]; self->_name = self->_prefix = nil; self->_last = self->_i + 1; self->_state = (self->_data[self->_i] == '>' | | < | | 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 | [self->_namespaces removeLastObject]; [self->_name release]; [self->_prefix release]; self->_name = self->_prefix = nil; self->_last = self->_i + 1; self->_state = (self->_data[self->_i] == '>' ? stateOutsideTag : stateExpectSpaceOrTagClose); if (self->_previous.count == 0) self->_finishedParsing = true; } /* Inside a tag, name found */ static void inTagState(OFXMLParser *self) { void *pool; OFString *namespace; OFXMLAttribute *const *attributesObjects; size_t attributesCount; if (self->_data[self->_i] != '>' && self->_data[self->_i] != '/') { if (self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' && self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r') { self->_last = self->_i; self->_state = stateInAttributeName; self->_i--; } return; } attributesObjects = self->_attributes.objects; |
︙ | ︙ | |||
764 765 766 767 768 769 770 | [self->_name release]; [self->_prefix release]; [self->_attributes removeAllObjects]; self->_name = self->_prefix = nil; self->_last = self->_i + 1; self->_state = (self->_data[self->_i] == '/' | | < | 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 | [self->_name release]; [self->_prefix release]; [self->_attributes removeAllObjects]; self->_name = self->_prefix = nil; self->_last = self->_i + 1; self->_state = (self->_data[self->_i] == '/' ? stateExpectTagClose : stateOutsideTag); } /* Looking for attribute name */ static void inAttributeNameState(OFXMLParser *self) { void *pool; |
︙ | ︙ | |||
813 814 815 816 817 818 819 | objc_autoreleasePoolPop(pool); [self->_buffer removeAllItems]; self->_last = self->_i + 1; self->_state = (self->_data[self->_i] == '=' | | < | | 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 | objc_autoreleasePoolPop(pool); [self->_buffer removeAllItems]; self->_last = self->_i + 1; self->_state = (self->_data[self->_i] == '=' ? stateExpectAttributeDelimiter : stateExpectAttributeEqualSign); } /* Expecting equal sign of an attribute */ static void expectAttributeEqualSignState(OFXMLParser *self) { if (self->_data[self->_i] == '=') { self->_last = self->_i + 1; self->_state = stateExpectAttributeDelimiter; return; } if (self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' && self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r') @throw [OFMalformedXMLException exceptionWithParser: self]; } |
︙ | ︙ | |||
846 847 848 849 850 851 852 | self->_data[self->_i] == '\n' || self->_data[self->_i] == '\r') return; if (self->_data[self->_i] != '\'' && self->_data[self->_i] != '"') @throw [OFMalformedXMLException exceptionWithParser: self]; self->_delimiter = self->_data[self->_i]; | | | 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 | self->_data[self->_i] == '\n' || self->_data[self->_i] == '\r') return; if (self->_data[self->_i] != '\'' && self->_data[self->_i] != '"') @throw [OFMalformedXMLException exceptionWithParser: self]; self->_delimiter = self->_data[self->_i]; self->_state = stateInAttributeValue; } /* Looking for attribute value */ static void inAttributeValueState(OFXMLParser *self) { void *pool; |
︙ | ︙ | |||
890 891 892 893 894 895 896 | [self->_buffer removeAllItems]; [self->_attributeName release]; [self->_attributePrefix release]; self->_attributeName = self->_attributePrefix = nil; self->_last = self->_i + 1; | | | | | | | | | 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 | [self->_buffer removeAllItems]; [self->_attributeName release]; [self->_attributePrefix release]; self->_attributeName = self->_attributePrefix = nil; self->_last = self->_i + 1; self->_state = stateInTag; } /* Expecting closing '>' */ static void expectTagCloseState(OFXMLParser *self) { if (self->_data[self->_i] == '>') { self->_last = self->_i + 1; self->_state = stateOutsideTag; } else @throw [OFMalformedXMLException exceptionWithParser: self]; } /* Expecting closing '>' or space */ static void expectSpaceOrTagCloseState(OFXMLParser *self) { if (self->_data[self->_i] == '>') { self->_last = self->_i + 1; self->_state = stateOutsideTag; } else if (self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' && self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r') @throw [OFMalformedXMLException exceptionWithParser: self]; } /* In <! */ static void inExclamationMarkState(OFXMLParser *self) { if (self->_finishedParsing && self->_data[self->_i] != '-') @throw [OFMalformedXMLException exceptionWithParser: self]; if (self->_data[self->_i] == '-') self->_state = stateInCommentOpening; else if (self->_data[self->_i] == '[') { self->_state = stateInCDATAOpening; self->_level = 0; } else if (self->_data[self->_i] == 'D') { self->_state = stateInDOCTYPE; self->_level = 0; } else @throw [OFMalformedXMLException exceptionWithParser: self]; self->_last = self->_i + 1; } /* CDATA */ static void inCDATAOpeningState(OFXMLParser *self) { if (self->_data[self->_i] != "CDATA["[self->_level]) @throw [OFMalformedXMLException exceptionWithParser: self]; if (++self->_level == 6) { self->_state = stateInCDATA; self->_level = 0; } self->_last = self->_i + 1; } static void |
︙ | ︙ | |||
968 969 970 971 972 973 974 | appendToBuffer(self->_buffer, self->_data + self->_last, self->_encoding, self->_i - self->_last); CDATA = transformString(self, self->_buffer, 2, false); if ([self->_delegate respondsToSelector: @selector(parser:foundCDATA:)]) | | < | | | | < | | | < | 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 | appendToBuffer(self->_buffer, self->_data + self->_last, self->_encoding, self->_i - self->_last); CDATA = transformString(self, self->_buffer, 2, false); if ([self->_delegate respondsToSelector: @selector(parser:foundCDATA:)]) [self->_delegate parser: self foundCDATA: CDATA]; objc_autoreleasePoolPop(pool); [self->_buffer removeAllItems]; self->_last = self->_i + 1; self->_state = stateOutsideTag; } else self->_level = 0; } /* Comment */ static void inCommentOpeningState(OFXMLParser *self) { if (self->_data[self->_i] != '-') @throw [OFMalformedXMLException exceptionWithParser: self]; self->_last = self->_i + 1; self->_state = stateInComment1; self->_level = 0; } static void inCommentState1(OFXMLParser *self) { if (self->_data[self->_i] == '-') self->_level++; else self->_level = 0; if (self->_level == 2) self->_state = stateInComment2; } static void inCommentState2(OFXMLParser *self) { void *pool; OFString *comment; if (self->_data[self->_i] != '>') @throw [OFMalformedXMLException exceptionWithParser: self]; pool = objc_autoreleasePoolPush(); appendToBuffer(self->_buffer, self->_data + self->_last, self->_encoding, self->_i - self->_last); comment = transformString(self, self->_buffer, 2, false); if ([self->_delegate respondsToSelector: @selector(parser:foundComment:)]) [self->_delegate parser: self foundComment: comment]; objc_autoreleasePoolPop(pool); [self->_buffer removeAllItems]; self->_last = self->_i + 1; self->_state = stateOutsideTag; } /* In <!DOCTYPE ...> */ static void inDOCTYPEState(OFXMLParser *self) { if ((self->_level < 6 && self->_data[self->_i] != "OCTYPE"[self->_level]) || (self->_level == 6 && self->_data[self->_i] != ' ' && self->_data[self->_i] != '\t' && self->_data[self->_i] != '\n' && self->_data[self->_i] != '\r')) @throw [OFMalformedXMLException exceptionWithParser: self]; self->_level++; if (self->_level > 6 && self->_data[self->_i] == '>') self->_state = stateOutsideTag; self->_last = self->_i + 1; } - (size_t)lineNumber { return _lineNumber; } - (bool)hasFinishedParsing { return _finishedParsing; } - (OFString *)string: (OFString *)string containsUnknownEntityNamed: (OFString *)entity { if ([_delegate respondsToSelector: @selector(parser:foundUnknownEntityNamed:)]) return [_delegate parser: self foundUnknownEntityNamed: entity]; return nil; } @end |
Renamed and modified src/OFXMLProcessingInstructions.h [a8a290f619] to src/OFXMLProcessingInstruction.h [c7ed4d9c0a].
1 | /* | < < | | | | | | | > > > > > > > > > > | > > | | | > | | > | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFXMLNode.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFXMLProcessingInstruction \ * OFXMLProcessingInstruction.h ObjFW/OFXMLProcessingInstruction.h * * @brief A class for representing an XML processing instruction. */ @interface OFXMLProcessingInstruction: OFXMLNode { OFString *_target, *_data; OF_RESERVE_IVARS(OFXMLProcessingInstruction, 4) } /** * @brief The target of the processing instruction. */ @property (readonly, nonatomic) OFString *target; /** * @brief The data of the processing instruction. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *data; /** * @brief Creates a new OFXMLProcessingInstruction with the specified target * and data. * * @param target The target for the processing instruction * @param data The data for the processing instruction * @return A new OFXMLProcessingInstruction */ + (instancetype)processingInstructionWithTarget: (OFString *)target data: (OFString *)data; /** * @brief Initializes an already allocated OFXMLProcessingInstruction with the * specified target and data. * * @param target The target for the processing instruction * @param data The data for the processing instruction * @return An initialized OFXMLProcessingInstruction */ - (instancetype)initWithTarget: (OFString *)target data: (OFString *)data OF_DESIGNATED_INITIALIZER; - (instancetype)initWithSerialization: (OFXMLElement *)element; @end OF_ASSUME_NONNULL_END |
Renamed and modified src/OFXMLProcessingInstructions.m [7c38ca2413] to src/OFXMLProcessingInstruction.m [16bf6dae0d].
1 | /* | < < | | | | > | > > | > | > | > > | < < > | > > > > > > | > | | | | > > > | | > > > > > > > > > > | > | > > > | < < < > | > | > > > > | | < < < | > > | | | | > | > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "OFXMLProcessingInstruction.h" #import "OFString.h" #import "OFXMLAttribute.h" #import "OFXMLElement.h" #import "OFXMLNode+Private.h" #import "OFInvalidArgumentException.h" @implementation OFXMLProcessingInstruction @synthesize target = _target, data = _data; + (instancetype)processingInstructionWithTarget: (OFString *)target data: (OFString *)data { return [[[self alloc] initWithTarget: target data: data] autorelease]; } - (instancetype)initWithTarget: (OFString *)target data: (OFString *)data { self = [super of_init]; @try { _target = [target copy]; _data = [data copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithSerialization: (OFXMLElement *)element { @try { void *pool = objc_autoreleasePoolPush(); OFXMLAttribute *targetAttr; if (![element.name isEqual: self.className] || ![element.namespace isEqual: OFSerializationNS]) @throw [OFInvalidArgumentException exception]; targetAttr = [element attributeForName: @"target" namespace: OFSerializationNS]; if (targetAttr.stringValue.length == 0) @throw [OFInvalidArgumentException exception]; self = [self initWithTarget: targetAttr.stringValue data: element.stringValue]; objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_target release]; [_data release]; [super dealloc]; } - (bool)isEqual: (id)object { OFXMLProcessingInstruction *processingInstruction; if (object == self) return true; if (![object isKindOfClass: [OFXMLProcessingInstruction class]]) return false; processingInstruction = object; if (![processingInstruction->_target isEqual: _target]) return false; if (processingInstruction->_data != _data && ![processingInstruction->_data isEqual: _data]) return false; return true; } - (unsigned long)hash { unsigned long hash; OFHashInit(&hash); OFHashAddHash(&hash, _target.hash); OFHashAddHash(&hash, _data.hash); OFHashFinalize(&hash); return hash; } - (OFString *)stringValue { return @""; } - (OFString *)XMLString { if (_data.length > 0) return [OFString stringWithFormat: @"<?%@ %@?>", _target, _data]; else return [OFString stringWithFormat: @"<?%@?>", _target]; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation { return self.XMLString; } - (OFString *)XMLStringWithIndentation: (unsigned int)indentation level: (unsigned int)level { if (indentation > 0 && level > 0) { OFString *ret; char *whitespaces = OFAllocMemory((level * indentation) + 1, 1); memset(whitespaces, ' ', level * indentation); whitespaces[level * indentation] = 0; @try { if (_data.length > 0) ret = [OFString stringWithFormat: @"%s<?%@ %@?>", whitespaces, _target, _data]; else ret = [OFString stringWithFormat: @"%s<?%@?>", whitespaces, _target]; } @finally { OFFreeMemory(whitespaces); } return ret; } else return self.XMLString; } - (OFString *)description { return self.XMLString; } - (OFXMLElement *)XMLElementBySerializing { OFXMLElement *ret = [OFXMLElement elementWithName: self.className namespace: OFSerializationNS stringValue: _data]; void *pool = objc_autoreleasePoolPush(); [ret addAttribute: [OFXMLAttribute attributeWithName: @"target" stringValue: _target]]; objc_autoreleasePoolPop(pool); return ret; } @end |
Modified src/OFZIPArchive.h from [e60923cb94] to [cd08e80056].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
32 33 34 35 36 37 38 | * @brief A class for accessing and manipulating ZIP files. */ OF_SUBCLASSING_RESTRICTED @interface OFZIPArchive: OFObject { OFStream *_stream; int64_t _offset; | < < < < | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | * @brief A class for accessing and manipulating ZIP files. */ OF_SUBCLASSING_RESTRICTED @interface OFZIPArchive: OFObject { OFStream *_stream; int64_t _offset; uint_least8_t _mode; uint32_t _diskNumber, _centralDirectoryDisk; uint64_t _centralDirectoryEntriesInDisk, _centralDirectoryEntries; uint64_t _centralDirectorySize; int64_t _centralDirectoryOffset; OFString *_Nullable _archiveComment; OFMutableArray OF_GENERIC(OFZIPArchiveEntry *) *_entries; OFMutableDictionary OF_GENERIC(OFString *, OFZIPArchiveEntry *) |
︙ | ︙ | |||
74 75 76 77 78 79 80 | * @param stream A stream from which the ZIP archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFZIPArchive */ | | < | < | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | * @param stream A stream from which the ZIP archive will be read. * For read and append mode, this needs to be an OFSeekableStream. * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFZIPArchive */ + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode; #ifdef OF_HAVE_FILES /** * @brief Creates a new OFZIPArchive object with the specified file. * * @param path The path to the ZIP file * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFZIPArchive */ + (instancetype)archiveWithPath: (OFString *)path mode: (OFString *)mode; #endif - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFZIPArchive object with the * specified stream. |
︙ | ︙ | |||
118 119 120 121 122 123 124 | * * @param path The path to the ZIP file * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFZIPArchive */ | | < | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | * * @param path The path to the ZIP file * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFZIPArchive */ - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode; #endif /** * @brief Returns a stream for reading the specified file from the archive. * * @note This method is only available in read mode. * |
︙ | ︙ | |||
172 173 174 175 176 177 178 179 180 | - (OFStream *)streamForWritingEntry: (OFZIPArchiveEntry *)entry; /** * @brief Closes the OFZIPArchive. */ - (void)close; @end OF_ASSUME_NONNULL_END | > > > > > > > > > > > | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | - (OFStream *)streamForWritingEntry: (OFZIPArchiveEntry *)entry; /** * @brief Closes the OFZIPArchive. */ - (void)close; @end #ifdef __cplusplus extern "C" { #endif extern uint32_t OFZIPArchiveReadField32(const uint8_t *_Nonnull *_Nonnull, uint16_t *_Nonnull); extern uint64_t OFZIPArchiveReadField64(const uint8_t *_Nonnull *_Nonnull, uint16_t *_Nonnull); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/OFZIPArchive.m from [6d9893fc0c] to [2bbedc5f4d].
1 | /* | < < | > < < > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFZIPArchive.h" #import "OFZIPArchiveEntry.h" #import "OFZIPArchiveEntry+Private.h" #import "OFCRC32.h" #import "OFData.h" #import "OFArray.h" #import "OFDictionary.h" #import "OFStream.h" #import "OFSeekableStream.h" #ifdef OF_HAVE_FILES # import "OFFile.h" #endif #import "OFInflateStream.h" #import "OFInflate64Stream.h" #import "OFChecksumMismatchException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #import "OFOpenItemFailedException.h" #import "OFOutOfRangeException.h" #import "OFSeekFailedException.h" #import "OFTruncatedDataException.h" #import "OFUnsupportedVersionException.h" #import "OFWriteFailedException.h" /* * FIXME: Current limitations: * - Split archives are not supported. * - Encrypted files cannot be read. */ enum { modeRead, modeWrite, modeAppend }; OF_DIRECT_MEMBERS @interface OFZIPArchive () - (void)of_readZIPInfo; - (void)of_readEntries; - (void)of_closeLastReturnedStream; - (void)of_writeCentralDirectory; |
︙ | ︙ | |||
101 102 103 104 105 106 107 | } - (instancetype)initWithStream: (OFStream *)stream entry: (OFMutableZIPArchiveEntry *)entry; @end uint32_t | | | | | < | < | < | < | < | < | | | | < | | | < | < | < | < | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | } - (instancetype)initWithStream: (OFStream *)stream entry: (OFMutableZIPArchiveEntry *)entry; @end uint32_t OFZIPArchiveReadField32(const uint8_t **data, uint16_t *size) { uint32_t field = 0; if (*size < 4) @throw [OFInvalidFormatException exception]; for (uint8_t i = 0; i < 4; i++) field |= (uint32_t)(*data)[i] << (i * 8); *data += 4; *size -= 4; return field; } uint64_t OFZIPArchiveReadField64(const uint8_t **data, uint16_t *size) { uint64_t field = 0; if (*size < 8) @throw [OFInvalidFormatException exception]; for (uint8_t i = 0; i < 8; i++) field |= (uint64_t)(*data)[i] << (i * 8); *data += 8; *size -= 8; return field; } static void seekOrThrowInvalidFormat(OFSeekableStream *stream, OFFileOffset offset, int whence) { @try { [stream seekToOffset: offset whence: whence]; } @catch (OFSeekFailedException *e) { if (e.errNo == EINVAL) @throw [OFInvalidFormatException exception]; @throw e; } } @implementation OFZIPArchive @synthesize archiveComment = _archiveComment; + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode { return [[[self alloc] initWithStream: stream mode: mode] autorelease]; } #ifdef OF_HAVE_FILES + (instancetype)archiveWithPath: (OFString *)path mode: (OFString *)mode { return [[[self alloc] initWithPath: path mode: mode] autorelease]; } #endif - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithStream: (OFStream *)stream mode: (OFString *)mode { self = [super init]; @try { if ([mode isEqual: @"r"]) _mode = modeRead; else if ([mode isEqual: @"w"]) _mode = modeWrite; else if ([mode isEqual: @"a"]) _mode = modeAppend; else @throw [OFInvalidArgumentException exception]; _stream = [stream retain]; _entries = [[OFMutableArray alloc] init]; _pathToEntryMap = [[OFMutableDictionary alloc] init]; if (_mode == modeRead || _mode == modeAppend) { if (![stream isKindOfClass: [OFSeekableStream class]]) @throw [OFInvalidArgumentException exception]; [self of_readZIPInfo]; [self of_readEntries]; } if (_mode == modeAppend) { _offset = _centralDirectoryOffset; seekOrThrowInvalidFormat((OFSeekableStream *)_stream, (OFFileOffset)_offset, SEEK_SET); } } @catch (id e) { /* * If we are in write or append mode, we do not want -[close] * to write anything to it on error - after all, it might not * be a ZIP file which we would destroy otherwise. */ [_stream release]; _stream = nil; [self release]; @throw e; } return self; } #ifdef OF_HAVE_FILES - (instancetype)initWithPath: (OFString *)path mode: (OFString *)mode { OFFile *file; if ([mode isEqual: @"a"]) file = [[OFFile alloc] initWithPath: path mode: @"r+"]; else file = [[OFFile alloc] initWithPath: path mode: mode]; @try { self = [self initWithStream: file mode: mode]; } @finally { [file release]; } return self; } #endif |
︙ | ︙ | |||
264 265 266 267 268 269 270 | [super dealloc]; } - (void)of_readZIPInfo { void *pool = objc_autoreleasePoolPush(); uint16_t commentLength; | | | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | [super dealloc]; } - (void)of_readZIPInfo { void *pool = objc_autoreleasePoolPush(); uint16_t commentLength; OFFileOffset offset = -22; bool valid = false; do { seekOrThrowInvalidFormat((OFSeekableStream *)_stream, offset, SEEK_END); if ([_stream readLittleEndianInt32] == 0x06054B50) { |
︙ | ︙ | |||
290 291 292 293 294 295 296 | _centralDirectoryEntries = [_stream readLittleEndianInt16]; _centralDirectorySize = [_stream readLittleEndianInt32]; _centralDirectoryOffset = [_stream readLittleEndianInt32]; commentLength = [_stream readLittleEndianInt16]; _archiveComment = [[_stream readStringWithLength: commentLength | | | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | _centralDirectoryEntries = [_stream readLittleEndianInt16]; _centralDirectorySize = [_stream readLittleEndianInt32]; _centralDirectoryOffset = [_stream readLittleEndianInt32]; commentLength = [_stream readLittleEndianInt16]; _archiveComment = [[_stream readStringWithLength: commentLength encoding: OFStringEncodingCodepage437] copy]; if (_diskNumber == 0xFFFF || _centralDirectoryDisk == 0xFFFF || _centralDirectoryEntriesInDisk == 0xFFFF || _centralDirectoryEntries == 0xFFFF || _centralDirectorySize == 0xFFFFFFFF || _centralDirectoryOffset == 0xFFFFFFFF) { |
︙ | ︙ | |||
316 317 318 319 320 321 322 | /* * FIXME: Handle number of the disk containing ZIP64 end of * central directory record. */ [_stream readLittleEndianInt32]; offset64 = [_stream readLittleEndianInt64]; | | | | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | /* * FIXME: Handle number of the disk containing ZIP64 end of * central directory record. */ [_stream readLittleEndianInt32]; offset64 = [_stream readLittleEndianInt64]; if (offset64 < 0 || (OFFileOffset)offset64 != offset64) @throw [OFOutOfRangeException exception]; seekOrThrowInvalidFormat((OFSeekableStream *)_stream, (OFFileOffset)offset64, SEEK_SET); if ([_stream readLittleEndianInt32] != 0x06064B50) @throw [OFInvalidFormatException exception]; size = [_stream readLittleEndianInt64]; if (size < 44) @throw [OFInvalidFormatException exception]; |
︙ | ︙ | |||
343 344 345 346 347 348 349 | _centralDirectoryEntriesInDisk = [_stream readLittleEndianInt64]; _centralDirectoryEntries = [_stream readLittleEndianInt64]; _centralDirectorySize = [_stream readLittleEndianInt64]; _centralDirectoryOffset = [_stream readLittleEndianInt64]; if (_centralDirectoryOffset < 0 || | | | | | < | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | _centralDirectoryEntriesInDisk = [_stream readLittleEndianInt64]; _centralDirectoryEntries = [_stream readLittleEndianInt64]; _centralDirectorySize = [_stream readLittleEndianInt64]; _centralDirectoryOffset = [_stream readLittleEndianInt64]; if (_centralDirectoryOffset < 0 || (OFFileOffset)_centralDirectoryOffset != _centralDirectoryOffset) @throw [OFOutOfRangeException exception]; } objc_autoreleasePoolPop(pool); } - (void)of_readEntries { void *pool = objc_autoreleasePoolPush(); if (_centralDirectoryOffset < 0 || (OFFileOffset)_centralDirectoryOffset != _centralDirectoryOffset) @throw [OFOutOfRangeException exception]; seekOrThrowInvalidFormat((OFSeekableStream *)_stream, (OFFileOffset)_centralDirectoryOffset, SEEK_SET); for (size_t i = 0; i < _centralDirectoryEntries; i++) { OFZIPArchiveEntry *entry = [[[OFZIPArchiveEntry alloc] of_initWithStream: _stream] autorelease]; if ([_pathToEntryMap objectForKey: entry.fileName] != nil) @throw [OFInvalidFormatException exception]; [_entries addObject: entry]; [_pathToEntryMap setObject: entry forKey: entry.fileName]; } objc_autoreleasePoolPop(pool); } - (OFArray *)entries { |
︙ | ︙ | |||
410 411 412 413 414 415 416 | { @try { [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ } | | < | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | { @try { [_lastReturnedStream close]; } @catch (OFNotOpenException *e) { /* Might have already been closed by the user - that's fine. */ } if ((_mode == modeWrite || _mode == modeAppend) && [_lastReturnedStream isKindOfClass: [OFZIPArchiveFileWriteStream class]]) { OFZIPArchiveFileWriteStream *stream = (OFZIPArchiveFileWriteStream *)_lastReturnedStream; if (INT64_MAX - _offset < stream->_bytesWritten) @throw [OFOutOfRangeException exception]; |
︙ | ︙ | |||
440 441 442 443 444 445 446 | - (OFStream *)streamForReadingFile: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFZIPArchiveEntry *entry; OFZIPArchiveLocalFileHeader *localFileHeader; int64_t offset64; | > > > | | | | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 | - (OFStream *)streamForReadingFile: (OFString *)path { void *pool = objc_autoreleasePoolPush(); OFZIPArchiveEntry *entry; OFZIPArchiveLocalFileHeader *localFileHeader; int64_t offset64; if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_mode != modeRead) @throw [OFInvalidArgumentException exception]; if ((entry = [_pathToEntryMap objectForKey: path]) == nil) @throw [OFOpenItemFailedException exceptionWithPath: path mode: @"r" errNo: ENOENT]; [self of_closeLastReturnedStream]; offset64 = entry.of_localFileHeaderOffset; if (offset64 < 0 || (OFFileOffset)offset64 != offset64) @throw [OFOutOfRangeException exception]; seekOrThrowInvalidFormat((OFSeekableStream *)_stream, (OFFileOffset)offset64, SEEK_SET); localFileHeader = [[[OFZIPArchiveLocalFileHeader alloc] initWithStream: _stream] autorelease]; if (![localFileHeader matchesEntry: entry]) @throw [OFInvalidFormatException exception]; if ((localFileHeader->_minVersionNeeded & 0xFF) > 45) { |
︙ | ︙ | |||
490 491 492 493 494 495 496 | int64_t offsetAdd = 0; void *pool; OFMutableZIPArchiveEntry *entry; OFString *fileName; OFData *extraField; uint16_t fileNameLength, extraFieldLength; | > > | | | < | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | int64_t offsetAdd = 0; void *pool; OFMutableZIPArchiveEntry *entry; OFString *fileName; OFData *extraField; uint16_t fileNameLength, extraFieldLength; if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_mode != modeWrite && _mode != modeAppend) @throw [OFInvalidArgumentException exception]; pool = objc_autoreleasePoolPush(); entry = [[entry_ mutableCopy] autorelease]; if ([_pathToEntryMap objectForKey: entry.fileName] != nil) @throw [OFOpenItemFailedException exceptionWithPath: entry.fileName mode: @"w" errNo: EEXIST]; if (entry.compressionMethod != OFZIPArchiveEntryCompressionMethodNone) @throw [OFNotImplementedException exceptionWithSelector: _cmd object: self]; [self of_closeLastReturnedStream]; fileName = entry.fileName; fileNameLength = fileName.UTF8StringLength; |
︙ | ︙ | |||
544 545 546 547 548 549 550 | [_stream writeLittleEndianInt16: fileNameLength]; [_stream writeLittleEndianInt16: extraFieldLength + 20]; offsetAdd += 4 + (5 * 2) + (3 * 4) + (2 * 2); [_stream writeString: fileName]; offsetAdd += fileNameLength; | | < | 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 | [_stream writeLittleEndianInt16: fileNameLength]; [_stream writeLittleEndianInt16: extraFieldLength + 20]; offsetAdd += 4 + (5 * 2) + (3 * 4) + (2 * 2); [_stream writeString: fileName]; offsetAdd += fileNameLength; [_stream writeLittleEndianInt16: OFZIPArchiveEntryExtraFieldTagZIP64]; [_stream writeLittleEndianInt16: 16]; /* We use the data descriptor */ [_stream writeLittleEndianInt64: 0]; [_stream writeLittleEndianInt64: 0]; offsetAdd += (2 * 2) + (2 * 8); if (extraField != nil) |
︙ | ︙ | |||
626 627 628 629 630 631 632 | - (void)close { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; [self of_closeLastReturnedStream]; | | < | | < | | | | | | | | 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 | - (void)close { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; [self of_closeLastReturnedStream]; if (_mode == modeWrite || _mode == modeAppend) [self of_writeCentralDirectory]; [_stream release]; _stream = nil; } @end @implementation OFZIPArchiveLocalFileHeader - (instancetype)initWithStream: (OFStream *)stream { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableData *extraField = nil; uint16_t fileNameLength, extraFieldLength; OFStringEncoding encoding; size_t ZIP64Index; uint16_t ZIP64Size; if ([stream readLittleEndianInt32] != 0x04034B50) @throw [OFInvalidFormatException exception]; _minVersionNeeded = [stream readLittleEndianInt16]; _generalPurposeBitFlag = [stream readLittleEndianInt16]; _compressionMethod = [stream readLittleEndianInt16]; _lastModifiedFileTime = [stream readLittleEndianInt16]; _lastModifiedFileDate = [stream readLittleEndianInt16]; _CRC32 = [stream readLittleEndianInt32]; _compressedSize = [stream readLittleEndianInt32]; _uncompressedSize = [stream readLittleEndianInt32]; fileNameLength = [stream readLittleEndianInt16]; extraFieldLength = [stream readLittleEndianInt16]; encoding = (_generalPurposeBitFlag & (1u << 11) ? OFStringEncodingUTF8 : OFStringEncodingCodepage437); _fileName = [[stream readStringWithLength: fileNameLength encoding: encoding] copy]; if (extraFieldLength > 0) extraField = [[[stream readDataWithCount: extraFieldLength] mutableCopy] autorelease]; ZIP64Index = OFZIPArchiveEntryExtraFieldFind(extraField, OFZIPArchiveEntryExtraFieldTagZIP64, &ZIP64Size); if (ZIP64Index != OFNotFound) { const uint8_t *ZIP64 = [extraField itemAtIndex: ZIP64Index]; OFRange range = OFRangeMake(ZIP64Index - 4, ZIP64Size + 4); if (_uncompressedSize == 0xFFFFFFFF) _uncompressedSize = OFZIPArchiveReadField64( &ZIP64, &ZIP64Size); if (_compressedSize == 0xFFFFFFFF) _compressedSize = OFZIPArchiveReadField64( &ZIP64, &ZIP64Size); if (ZIP64Size > 0) @throw [OFInvalidFormatException exception]; [extraField removeItemsInRange: range]; } |
︙ | ︙ | |||
745 746 747 748 749 750 751 | { self = [super init]; @try { _stream = [stream retain]; switch (entry.compressionMethod) { | | | | | 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 | { self = [super init]; @try { _stream = [stream retain]; switch (entry.compressionMethod) { case OFZIPArchiveEntryCompressionMethodNone: _decompressedStream = [stream retain]; break; case OFZIPArchiveEntryCompressionMethodDeflate: _decompressedStream = [[OFInflateStream alloc] initWithStream: stream]; break; case OFZIPArchiveEntryCompressionMethodDeflate64: _decompressedStream = [[OFInflate64Stream alloc] initWithStream: stream]; break; default: @throw [OFNotImplementedException exceptionWithSelector: _cmd object: nil]; |
︙ | ︙ | |||
791 792 793 794 795 796 797 | { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } | | < | < | | 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 | { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { size_t ret; if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; if (_atEndOfStream) return 0; if (_stream.atEndOfStream && !_decompressedStream.hasDataInReadBuffer) @throw [OFTruncatedDataException exception]; #if SIZE_MAX >= UINT64_MAX if (length > UINT64_MAX) @throw [OFOutOfRangeException exception]; #endif if ((uint64_t)length > _toRead) length = (size_t)_toRead; ret = [_decompressedStream readIntoBuffer: buffer length: length]; _toRead -= ret; _CRC32 = OFCRC32(_CRC32, buffer, ret); if (_toRead == 0) { _atEndOfStream = true; if (~_CRC32 != _entry.CRC32) { OFString *actualChecksum = [OFString stringWithFormat: @"%08" PRIX32, ~_CRC32]; |
︙ | ︙ | |||
887 888 889 890 891 892 893 | [self close]; [_entry release]; [super dealloc]; } | | < < < > | > > | > > > > > > > > | | | | 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 | [self close]; [_entry release]; [super dealloc]; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { #if SIZE_MAX >= INT64_MAX if (length > INT64_MAX) @throw [OFOutOfRangeException exception]; #endif if (INT64_MAX - _bytesWritten < (int64_t)length) @throw [OFOutOfRangeException exception]; @try { [_stream writeBuffer: buffer length: length]; } @catch (OFWriteFailedException *e) { OFEnsure(e.bytesWritten <= length); _bytesWritten += (int64_t)e.bytesWritten; _CRC32 = OFCRC32(_CRC32, buffer, e.bytesWritten); if (e.errNo == EWOULDBLOCK || e.errNo == EAGAIN) return e.bytesWritten; @throw e; } _bytesWritten += (int64_t)length; _CRC32 = OFCRC32(_CRC32, buffer, length); return length; } - (void)close { if (_stream == nil) @throw [OFNotOpenException exceptionWithObject: self]; |
︙ | ︙ |
Modified src/OFZIPArchiveEntry+Private.h from [19e5b08dac] to [9241ef29c2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/OFZIPArchiveEntry.h from [b2722b6f23] to [053b7bad8d].
1 | /* | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > | > | < > > > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" OF_ASSUME_NONNULL_BEGIN /** @file */ typedef enum { OFZIPArchiveEntryCompressionMethodNone = 0, OFZIPArchiveEntryCompressionMethodShrink = 1, OFZIPArchiveEntryCompressionMethodReduceFactor1 = 2, OFZIPArchiveEntryCompressionMethodReduceFactor2 = 3, OFZIPArchiveEntryCompressionMethodReduceFactor3 = 4, OFZIPArchiveEntryCompressionMethodReduceFactor4 = 5, OFZIPArchiveEntryCompressionMethodImplode = 6, OFZIPArchiveEntryCompressionMethodDeflate = 8, OFZIPArchiveEntryCompressionMethodDeflate64 = 9, OFZIPArchiveEntryCompressionMethodBZIP2 = 12, OFZIPArchiveEntryCompressionMethodLZMA = 14, OFZIPArchiveEntryCompressionMethodWavPack = 97, OFZIPArchiveEntryCompressionMethodPPMd = 98 } OFZIPArchiveEntryCompressionMethod; /** * @brief Attribute compatibility part of ZIP versions. */ typedef enum { /** MS-DOS and OS/2 */ OFZIPArchiveEntryAttributeCompatibilityMSDOS = 0, /** Amiga */ OFZIPArchiveEntryAttributeCompatibilityAmiga = 1, /** OpenVMS */ OFZIPArchiveEntryAttributeCompatibilityOpenVMS = 2, /** UNIX */ OFZIPArchiveEntryAttributeCompatibilityUNIX = 3, /** VM/CMS */ OFZIPArchiveEntryAttributeCompatibilityVM_CMS = 4, /** Atari ST */ OFZIPArchiveEntryAttributeCompatibilityAtariST = 5, /** OS/2 HPFS */ OFZIPArchiveEntryAttributeCompatibilityOS2HPFS = 6, /** Macintosh */ OFZIPArchiveEntryAttributeCompatibilityMacintosh = 7, /** Z-System */ OFZIPArchiveEntryAttributeCompatibilityZSystem = 8, /** CP/M */ OFZIPArchiveEntryAttributeCompatibilityCPM = 9, /** Windows NTFS */ OFZIPArchiveEntryAttributeCompatibilityWindowsNTFS = 10, /** MVS (OS/390 - Z/OS) */ OFZIPArchiveEntryAttributeCompatibilityMVS = 11, /** VSE */ OFZIPArchiveEntryAttributeCompatibilityVSE = 12, /** Acorn RISC OS */ OFZIPArchiveEntryAttributeCompatibilityAcornRISCOS = 13, /** VFAT */ OFZIPArchiveEntryAttributeCompatibilityVFAT = 14, /** Alternate MVS */ OFZIPArchiveEntryAttributeCompatibilityAlternateMVS = 15, /** BeOS */ OFZIPArchiveEntryAttributeCompatibilityBeOS = 16, /** Tandem */ OFZIPArchiveEntryAttributeCompatibilityTandem = 17, /** OS/400 */ OFZIPArchiveEntryAttributeCompatibilityOS400 = 18, /** OS X (Darwin) */ OFZIPArchiveEntryAttributeCompatibilityOSX = 19 } OFZIPArchiveEntryAttributeCompatibility; /** * @brief Tags for the extra field. */ typedef enum { /** ZIP64 extra field tag */ OFZIPArchiveEntryExtraFieldTagZIP64 = 0x0001 } OFZIPArchiveEntryExtraFieldTag; @class OFString; @class OFData; @class OFFile; @class OFDate; /** * @class OFZIPArchiveEntry OFZIPArchiveEntry.h ObjFW/OFZIPArchiveEntry.h * * @brief A class which represents an entry in the central directory of a ZIP * archive. */ @interface OFZIPArchiveEntry: OFObject <OFCopying, OFMutableCopying> { OFZIPArchiveEntryAttributeCompatibility _versionMadeBy; OFZIPArchiveEntryAttributeCompatibility _minVersionNeeded; uint16_t _generalPurposeBitFlag; OFZIPArchiveEntryCompressionMethod _compressionMethod; uint16_t _lastModifiedFileTime, _lastModifiedFileDate; uint32_t _CRC32; uint64_t _compressedSize, _uncompressedSize; OFString *_fileName; OFData *_Nullable _extraField; OFString *_Nullable _fileComment; uint32_t _startDiskNumber; |
︙ | ︙ | |||
134 135 136 137 138 139 140 | @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFData *extraField; /** * @brief The version which made the entry. * * The lower 8 bits are the ZIP specification version.@n * The upper 8 bits are the attribute compatibility. | | | > | | > | | | | | | > | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFData *extraField; /** * @brief The version which made the entry. * * The lower 8 bits are the ZIP specification version.@n * The upper 8 bits are the attribute compatibility. * See @ref OFZIPArchiveEntryAttributeCompatibility. */ @property (readonly, nonatomic) OFZIPArchiveEntryAttributeCompatibility versionMadeBy; /** * @brief The minimum version required to extract the file. * * The lower 8 bits are the ZIP specification version.@n * The upper 8 bits are the attribute compatibility. * See @ref OFZIPArchiveEntryAttributeCompatibility. */ @property (readonly, nonatomic) OFZIPArchiveEntryAttributeCompatibility minVersionNeeded; /** * @brief The last modification date of the entry's file. * * @note Due to limitations of the ZIP format, this has only 2 second precision. */ @property (readonly, retain, nonatomic) OFDate *modificationDate; /** * @brief The compression method of the entry. * * Supported values are: * Value | Description * --------------------------------------------|--------------- * OFZIPArchiveEntryCompressionMethodNone | No compression * OFZIPArchiveEntryCompressionMethodDeflate | Deflate * OFZIPArchiveEntryCompressionMethodDeflate64 | Deflate64 * * Other values may be returned, but the file cannot be extracted then. */ @property (readonly, nonatomic) OFZIPArchiveEntryCompressionMethod compressionMethod; /** * @brief The compressed size of the entry's file. */ @property (readonly, nonatomic) uint64_t compressedSize; /** |
︙ | ︙ | |||
227 228 229 230 231 232 233 | #endif /** * @brief Converts the ZIP entry version to a string. * * @param version The ZIP entry version to convert to a string * @return The ZIP entry version as a string */ | | | | | | | | 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | #endif /** * @brief Converts the ZIP entry version to a string. * * @param version The ZIP entry version to convert to a string * @return The ZIP entry version as a string */ extern OFString *OFZIPArchiveEntryVersionToString(uint16_t version); /** * @brief Convers the ZIP entry compression method to a string. * * @param compressionMethod The ZIP entry compression method to convert to a * string * @return The ZIP entry compression method as a string */ extern OFString *OFZIPArchiveEntryCompressionMethodName( OFZIPArchiveEntryCompressionMethod compressionMethod); /** * @brief Gets a pointer to and the size of the extensible data field with the * specified tag. * * @param extraField The extra field to search for an extensible data field with * the specified tag * @param tag The tag to look for * @param size A pointer to an uint16_t that should be set to the size * @return The index at which the extra field content starts in the OFData, or * `OFNotFound` */ extern size_t OFZIPArchiveEntryExtraFieldFind(OFData *extraField, OFZIPArchiveEntryExtraFieldTag tag, uint16_t *size); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END #import "OFMutableZIPArchiveEntry.h" |
Modified src/OFZIPArchiveEntry.m from [17d05978cb] to [6b838273dc].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | #import "OFStream.h" #import "OFString.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" | < < < | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | #import "OFStream.h" #import "OFString.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" OFString * OFZIPArchiveEntryVersionToString(uint16_t version) { const char *attrCompat = NULL; switch (version >> 8) { case OFZIPArchiveEntryAttributeCompatibilityMSDOS: attrCompat = "MS-DOS or OS/2"; break; case OFZIPArchiveEntryAttributeCompatibilityAmiga: attrCompat = "Amiga"; break; case OFZIPArchiveEntryAttributeCompatibilityOpenVMS: attrCompat = "OpenVMS"; break; case OFZIPArchiveEntryAttributeCompatibilityUNIX: attrCompat = "UNIX"; break; case OFZIPArchiveEntryAttributeCompatibilityVM_CMS: attrCompat = "VM/CMS"; break; case OFZIPArchiveEntryAttributeCompatibilityAtariST: attrCompat = "Atari ST"; break; case OFZIPArchiveEntryAttributeCompatibilityOS2HPFS: attrCompat = "OS/2 HPFS"; break; case OFZIPArchiveEntryAttributeCompatibilityMacintosh: attrCompat = "Macintosh"; break; case OFZIPArchiveEntryAttributeCompatibilityZSystem: attrCompat = "Z-System"; break; case OFZIPArchiveEntryAttributeCompatibilityCPM: attrCompat = "CP/M"; break; case OFZIPArchiveEntryAttributeCompatibilityWindowsNTFS: attrCompat = "Windows NTFS"; break; case OFZIPArchiveEntryAttributeCompatibilityMVS: attrCompat = "MVS (OS/390 - Z/OS)"; break; case OFZIPArchiveEntryAttributeCompatibilityVSE: attrCompat = "VSE"; break; case OFZIPArchiveEntryAttributeCompatibilityAcornRISCOS: attrCompat = "Acorn RISC OS"; break; case OFZIPArchiveEntryAttributeCompatibilityVFAT: attrCompat = "VFAT"; break; case OFZIPArchiveEntryAttributeCompatibilityAlternateMVS: attrCompat = "Alternate MVS"; break; case OFZIPArchiveEntryAttributeCompatibilityBeOS: attrCompat = "BeOS"; break; case OFZIPArchiveEntryAttributeCompatibilityTandem: attrCompat = "Tandem"; break; case OFZIPArchiveEntryAttributeCompatibilityOS400: attrCompat = "OS/400"; break; case OFZIPArchiveEntryAttributeCompatibilityOSX: attrCompat = "OS X (Darwin)"; break; } if (attrCompat != NULL) return [OFString stringWithFormat: @"%u.%u, %s", (version & 0xFF) / 10, (version & 0xFF) % 10, attrCompat]; else return [OFString stringWithFormat: @"%u.%u, unknown %02X", (version % 0xFF) / 10, (version & 0xFF) % 10, version >> 8]; } OFString * OFZIPArchiveEntryCompressionMethodName( OFZIPArchiveEntryCompressionMethod compressionMethod) { switch (compressionMethod) { case OFZIPArchiveEntryCompressionMethodNone: return @"none"; case OFZIPArchiveEntryCompressionMethodShrink: return @"Shrink"; case OFZIPArchiveEntryCompressionMethodReduceFactor1: return @"Reduce (factor 1)"; case OFZIPArchiveEntryCompressionMethodReduceFactor2: return @"Reduce (factor 2)"; case OFZIPArchiveEntryCompressionMethodReduceFactor3: return @"Reduce (factor 3)"; case OFZIPArchiveEntryCompressionMethodReduceFactor4: return @"Reduce (factor 4)"; case OFZIPArchiveEntryCompressionMethodImplode: return @"Implode"; case OFZIPArchiveEntryCompressionMethodDeflate: return @"Deflate"; case OFZIPArchiveEntryCompressionMethodDeflate64: return @"Deflate64"; case OFZIPArchiveEntryCompressionMethodBZIP2: return @"BZip2"; case OFZIPArchiveEntryCompressionMethodLZMA: return @"LZMA"; case OFZIPArchiveEntryCompressionMethodWavPack: return @"WavPack"; case OFZIPArchiveEntryCompressionMethodPPMd: return @"PPMd"; default: return @"unknown"; } } size_t OFZIPArchiveEntryExtraFieldFind(OFData *extraField, OFZIPArchiveEntryExtraFieldTag tag, uint16_t *size) { const uint8_t *bytes = extraField.items; size_t count = extraField.count; for (size_t i = 0; i < count;) { uint16_t currentTag, currentSize; |
︙ | ︙ | |||
168 169 170 171 172 173 174 | return i + 4; } i += 4 + currentSize; } *size = 0; | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | return i + 4; } i += 4 + currentSize; } *size = 0; return OFNotFound; } @implementation OFZIPArchiveEntry + (instancetype)entryWithFileName: (OFString *)fileName { return [[[self alloc] initWithFileName: fileName] autorelease]; } |
︙ | ︙ | |||
211 212 213 214 215 216 217 | { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableData *extraField = nil; uint16_t fileNameLength, extraFieldLength, fileCommentLength; | | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); OFMutableData *extraField = nil; uint16_t fileNameLength, extraFieldLength, fileCommentLength; OFStringEncoding encoding; size_t ZIP64Index; uint16_t ZIP64Size; if ([stream readLittleEndianInt32] != 0x02014B50) @throw [OFInvalidFormatException exception]; _versionMadeBy = [stream readLittleEndianInt16]; |
︙ | ︙ | |||
236 237 238 239 240 241 242 | fileCommentLength = [stream readLittleEndianInt16]; _startDiskNumber = [stream readLittleEndianInt16]; _internalAttributes = [stream readLittleEndianInt16]; _versionSpecificAttributes = [stream readLittleEndianInt32]; _localFileHeaderOffset = [stream readLittleEndianInt32]; encoding = (_generalPurposeBitFlag & (1u << 11) | | < | | | | | | | < | | | 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | fileCommentLength = [stream readLittleEndianInt16]; _startDiskNumber = [stream readLittleEndianInt16]; _internalAttributes = [stream readLittleEndianInt16]; _versionSpecificAttributes = [stream readLittleEndianInt32]; _localFileHeaderOffset = [stream readLittleEndianInt32]; encoding = (_generalPurposeBitFlag & (1u << 11) ? OFStringEncodingUTF8 : OFStringEncodingCodepage437); _fileName = [[stream readStringWithLength: fileNameLength encoding: encoding] copy]; if (extraFieldLength > 0) extraField = [[[stream readDataWithCount: extraFieldLength] mutableCopy] autorelease]; if (fileCommentLength > 0) _fileComment = [[stream readStringWithLength: fileCommentLength encoding: encoding] copy]; ZIP64Index = OFZIPArchiveEntryExtraFieldFind(extraField, OFZIPArchiveEntryExtraFieldTagZIP64, &ZIP64Size); if (ZIP64Index != OFNotFound) { const uint8_t *ZIP64 = [extraField itemAtIndex: ZIP64Index]; OFRange range = OFRangeMake(ZIP64Index - 4, ZIP64Size + 4); if (_uncompressedSize == 0xFFFFFFFF) _uncompressedSize = OFZIPArchiveReadField64( &ZIP64, &ZIP64Size); if (_compressedSize == 0xFFFFFFFF) _compressedSize = OFZIPArchiveReadField64( &ZIP64, &ZIP64Size); if (_localFileHeaderOffset == 0xFFFFFFFF) _localFileHeaderOffset = OFZIPArchiveReadField64(&ZIP64, &ZIP64Size); if (_startDiskNumber == 0xFFFF) _startDiskNumber = OFZIPArchiveReadField32( &ZIP64, &ZIP64Size); if (ZIP64Size > 0 || _localFileHeaderOffset < 0) @throw [OFInvalidFormatException exception]; [extraField removeItemsInRange: range]; } |
︙ | ︙ | |||
350 351 352 353 354 355 356 | } - (OFData *)extraField { return _extraField; } | | | | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | } - (OFData *)extraField { return _extraField; } - (OFZIPArchiveEntryAttributeCompatibility)versionMadeBy { return _versionMadeBy; } - (OFZIPArchiveEntryAttributeCompatibility)minVersionNeeded { return _minVersionNeeded; } - (OFDate *)modificationDate { void *pool = objc_autoreleasePoolPush(); |
︙ | ︙ | |||
384 385 386 387 388 389 390 | format: @"%Y-%m-%d %H:%M:%S"]; objc_autoreleasePoolPop(pool); return [date autorelease]; } | | | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 | format: @"%Y-%m-%d %H:%M:%S"]; objc_autoreleasePoolPop(pool); return [date autorelease]; } - (OFZIPArchiveEntryCompressionMethod)compressionMethod { return _compressionMethod; } - (uint64_t)compressedSize { return _compressedSize; |
︙ | ︙ | |||
433 434 435 436 437 438 439 | return _localFileHeaderOffset; } - (OFString *)description { void *pool = objc_autoreleasePoolPush(); OFString *compressionMethod = | < | | 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | return _localFileHeaderOffset; } - (OFString *)description { void *pool = objc_autoreleasePoolPush(); OFString *compressionMethod = OFZIPArchiveEntryCompressionMethodName(_compressionMethod); OFString *ret = [OFString stringWithFormat: @"<%@:\n" @"\tFile name = %@\n" @"\tFile comment = %@\n" @"\tGeneral purpose bit flag = %u\n" @"\tCompressed size = %" @PRIu64 "\n" @"\tUncompressed size = %" @PRIu64 "\n" |
︙ | ︙ | |||
489 490 491 492 493 494 495 | [stream writeLittleEndianInt32: _versionSpecificAttributes]; [stream writeLittleEndianInt32: 0xFFFFFFFF]; size += (4 + (6 * 2) + (3 * 4) + (5 * 2) + (2 * 4)); [stream writeString: _fileName]; size += (uint64_t)_fileName.UTF8StringLength; | | | 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 | [stream writeLittleEndianInt32: _versionSpecificAttributes]; [stream writeLittleEndianInt32: 0xFFFFFFFF]; size += (4 + (6 * 2) + (3 * 4) + (5 * 2) + (2 * 4)); [stream writeString: _fileName]; size += (uint64_t)_fileName.UTF8StringLength; [stream writeLittleEndianInt16: OFZIPArchiveEntryExtraFieldTagZIP64]; [stream writeLittleEndianInt16: 28]; [stream writeLittleEndianInt64: _uncompressedSize]; [stream writeLittleEndianInt64: _compressedSize]; [stream writeLittleEndianInt64: _localFileHeaderOffset]; [stream writeLittleEndianInt32: _startDiskNumber]; size += (2 * 2) + (3 * 8) + 4; |
︙ | ︙ |
Modified src/ObjFW.h from [117174bdb9] to [8e529c90da].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | #import "OFNull.h" #import "OFMethodSignature.h" #import "OFInvocation.h" #import "OFNumber.h" #import "OFDate.h" #import "OFURL.h" #import "OFURLHandler.h" #import "OFColor.h" #import "OFStream.h" #import "OFStdIOStream.h" #import "OFInflateStream.h" #import "OFInflate64Stream.h" #import "OFGZIPStream.h" #import "OFLHAArchive.h" #import "OFLHAArchiveEntry.h" | > > > > | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #import "OFNull.h" #import "OFMethodSignature.h" #import "OFInvocation.h" #import "OFNumber.h" #import "OFDate.h" #import "OFUUID.h" #import "OFURL.h" #import "OFURLHandler.h" #import "OFColor.h" #import "OFNotification.h" #import "OFNotificationCenter.h" #import "OFStream.h" #import "OFStdIOStream.h" #import "OFInflateStream.h" #import "OFInflate64Stream.h" #import "OFGZIPStream.h" #import "OFLHAArchive.h" #import "OFLHAArchiveEntry.h" |
︙ | ︙ | |||
70 71 72 73 74 75 76 | #endif #ifdef OF_HAVE_SOCKETS # import "OFStreamSocket.h" # import "OFDatagramSocket.h" # import "OFSequencedPacketSocket.h" # import "OFTCPSocket.h" # import "OFUDPSocket.h" | | | > | | | | | < < < < < < < < < < < < < | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | #endif #ifdef OF_HAVE_SOCKETS # import "OFStreamSocket.h" # import "OFDatagramSocket.h" # import "OFSequencedPacketSocket.h" # import "OFTCPSocket.h" # import "OFUDPSocket.h" # import "OFTLSStream.h" # import "OFKernelEventObserver.h" # import "OFDNSQuery.h" # import "OFDNSResourceRecord.h" # import "OFDNSResponse.h" # import "OFDNSResolver.h" # ifdef OF_HAVE_IPX # import "OFIPXSocket.h" # import "OFSPXSocket.h" # import "OFSPXStreamSocket.h" # endif # ifdef OF_HAVE_UNIX_SOCKETS # import "OFUNIXDatagramSocket.h" # import "OFUNIXStreamSocket.h" # endif #endif #ifdef OF_HAVE_SOCKETS # ifdef OF_HAVE_THREADS # import "OFHTTPClient.h" # endif # import "OFHTTPCookie.h" # import "OFHTTPCookieManager.h" # import "OFHTTPRequest.h" # import "OFHTTPResponse.h" # import "OFHTTPServer.h" #endif #ifdef OF_HAVE_SUBPROCESSES # import "OFSubprocess.h" #endif #import "OFCryptographicHash.h" #import "OFMD5Hash.h" #import "OFRIPEMD160Hash.h" #import "OFSHA1Hash.h" #import "OFSHA224Hash.h" #import "OFSHA256Hash.h" #import "OFSHA384Hash.h" #import "OFSHA512Hash.h" #import "OFHMAC.h" #import "OFXMLAttribute.h" #import "OFXMLElement.h" #import "OFXMLAttribute.h" #import "OFXMLCharacters.h" #import "OFXMLCDATA.h" #import "OFXMLComment.h" #import "OFXMLProcessingInstruction.h" #import "OFXMLParser.h" #import "OFXMLElementBuilder.h" #import "OFMessagePackExtension.h" #import "OFApplication.h" #import "OFSystemInfo.h" #import "OFLocale.h" #import "OFOptionsParser.h" #import "OFTimer.h" #import "OFRunLoop.h" #ifdef OF_WINDOWS # import "OFWindowsRegistryKey.h" #endif #import "OFAllocFailedException.h" #import "OFException.h" #ifdef OF_HAVE_SOCKETS # import "OFAcceptFailedException.h" # import "OFAlreadyConnectedException.h" # import "OFBindFailedException.h" #endif |
︙ | ︙ | |||
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | # import "OFGetCurrentDirectoryPathFailedException.h" #endif #import "OFGetOptionFailedException.h" #ifdef OF_WINDOWS # import "OFGetWindowsRegistryValueFailedException.h" #endif #import "OFHashAlreadyCalculatedException.h" #ifdef OF_HAVE_SOCKETS # import "OFHTTPRequestFailedException.h" #endif #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFInvalidJSONException.h" #import "OFInvalidServerReplyException.h" #import "OFLinkFailedException.h" #ifdef OF_HAVE_SOCKETS # import "OFListenFailedException.h" #endif #ifdef OF_HAVE_PLUGINS # import "OFLoadPluginFailedException.h" #endif #import "OFLockFailedException.h" #import "OFMalformedXMLException.h" | > < < > > > | < | | | | | < | | | < | | < < < < < < < < | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | # import "OFGetCurrentDirectoryPathFailedException.h" #endif #import "OFGetOptionFailedException.h" #ifdef OF_WINDOWS # import "OFGetWindowsRegistryValueFailedException.h" #endif #import "OFHashAlreadyCalculatedException.h" #import "OFHashNotCalculatedException.h" #ifdef OF_HAVE_SOCKETS # import "OFHTTPRequestFailedException.h" #endif #import "OFInitializationFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidEncodingException.h" #import "OFInvalidFormatException.h" #import "OFInvalidJSONException.h" #import "OFInvalidServerReplyException.h" #import "OFLinkFailedException.h" #ifdef OF_HAVE_SOCKETS # import "OFListenFailedException.h" #endif #ifdef OF_HAVE_PLUGINS # import "OFLoadPluginFailedException.h" #endif #import "OFLockFailedException.h" #import "OFMalformedXMLException.h" #import "OFMoveItemFailedException.h" #import "OFNotImplementedException.h" #import "OFNotOpenException.h" #ifdef OF_HAVE_SOCKETS # import "OFObserveFailedException.h" #endif #import "OFOpenItemFailedException.h" #ifdef OF_WINDOWS # import "OFOpenWindowsRegistryKeyFailedException.h" #endif #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFReadOrWriteFailedException.h" #import "OFRemoveItemFailedException.h" #ifdef OF_HAVE_SOCKETS # import "OFResolveHostFailedException.h" #endif #import "OFRetrieveItemAttributesFailedException.h" #import "OFSeekFailedException.h" #import "OFSetItemAttributesFailedException.h" #import "OFSetOptionFailedException.h" #ifdef OF_WINDOWS # import "OFSetWindowsRegistryValueFailedException.h" #endif #import "OFStillLockedException.h" #ifdef OF_HAVE_THREADS # import "OFThreadJoinFailedException.h" # import "OFThreadStartFailedException.h" # import "OFThreadStillRunningException.h" #endif #ifdef OF_HAVE_SOCKETS # import "OFTLSHandshakeFailedException.h" #endif #import "OFTruncatedDataException.h" #import "OFUnboundNamespaceException.h" #import "OFUnboundPrefixException.h" #import "OFUndefinedKeyException.h" #import "OFUnknownXMLEntityException.h" #import "OFUnlockFailedException.h" #import "OFUnsupportedProtocolException.h" #import "OFUnsupportedVersionException.h" #import "OFWriteFailedException.h" #ifdef OF_HAVE_PLUGINS # import "OFPlugin.h" #endif #ifdef OF_HAVE_ATOMIC_OPS # import "OFAtomic.h" #endif #import "OFLocking.h" #import "OFOnce.h" #import "OFThread.h" #ifdef OF_HAVE_THREADS # import "OFCondition.h" # import "OFMutex.h" # import "OFPlainCondition.h" # import "OFPlainMutex.h" # import "OFPlainThread.h" # import "OFRecursiveMutex.h" # import "OFTLSKey.h" #endif #import "OFPBKDF2.h" #import "OFScrypt.h" |
Deleted src/atomic_no_threads.h version [ed5f442394].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/block.h version [6724cf2142].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/bridge/NSArray+OFObject.h from [96da5e364a] to [4b59b82d97].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSArray+OFObject.m from [2163b64d79] to [a7c2336812].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSBridging.h from [5f30946c24] to [1aa6518645].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSDictionary+OFObject.h from [416324c2d3] to [1dcde481c6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSDictionary+OFObject.m from [61195e4046] to [3bee09377c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSEnumerator+OFObject.h from [5d278f1dcb] to [5e37d187b7].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSEnumerator+OFObject.m from [fc63efa4f6] to [dd0762c949].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSNumber+OFObject.h from [79c9621d37] to [bd31c0c3cd].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSNumber+OFObject.m from [a79897d657] to [18f7ec56ae].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSOFArray.h from [66e744b7e0] to [cd8e3e0488].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSOFArray.m from [5ca650b9c7] to [41ea305080].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSOFDictionary.h from [51287f6e15] to [b628e7e6a3].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSOFDictionary.m from [992ca34ebe] to [e47773ee01].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSOFEnumerator.h from [fc80d78d26] to [fcb10c08ed].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSOFEnumerator.m from [8af097925c] to [ebbed84f33].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSOFSet.h from [05ef212378] to [33948f6157].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSOFSet.m from [bb7bda884f] to [e7387e2762].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSSet+OFObject.h from [36a48785da] to [68cb6c5ccf].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSSet+OFObject.m from [ce021d5ef0] to [5daeb1bac4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSString+OFObject.h from [a36e06c85f] to [a30f21642d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/NSString+OFObject.m from [6eccedb527] to [f6fbd9f898].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFArray+NSObject.h from [ddd32da320] to [f258ecab9a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFArray+NSObject.m from [b153739fac] to [ee4c5a25af].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFBridging.h from [64c0fc4ba9] to [abe87031bc].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFDictionary+NSObject.h from [18dcc7538d] to [27bfd0d589].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFDictionary+NSObject.m from [d35c1e81fe] to [6df9e22408].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFEnumerator+NSObject.h from [d90c90d947] to [cb0752d99c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFEnumerator+NSObject.m from [f173918960] to [a3ee1dfe29].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFException+Swift.h from [3aecaa6184] to [da5307c0ad].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
45 46 47 48 49 50 51 | * @brief Execute the specified try block and finally call the finally block. * * @note This is only useful for Swift. * * @param try The try block to execute * @param finally The finally block to call at the end */ | | < | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | * @brief Execute the specified try block and finally call the finally block. * * @note This is only useful for Swift. * * @param try The try block to execute * @param finally The finally block to call at the end */ + (void)try: (void (^)(void))try finally: (void (^)(void))finally; /** * @brief Execute the specified try block and call the catch block if an * OFException occurred and finally call the finally block. * * @note This is only useful to catch OFExceptions in Swift. * |
︙ | ︙ |
Modified src/bridge/OFException+Swift.m from [ebdcbc4eab] to [69103747b4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFNSArray.h from [6f62085ac5] to [1c05dea53b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFNSArray.m from [a1ec973a29] to [511fcf77df].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFNSDictionary.h from [31d9760029] to [3699212d07].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFNSDictionary.m from [2365a3fbd3] to [3228b094f1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFNSEnumerator.h from [9fd573cd7f] to [f60938ebf6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFNSEnumerator.m from [f6021ac455] to [9f5d7028e9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFNSSet.h from [a6b44f6f41] to [7b3370ed57].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFNSSet.m from [85734e4123] to [151a52ad4b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFNumber+NSObject.h from [9042629e9c] to [955839af4e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFNumber+NSObject.m from [444f15ed81] to [f73968ae16].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFSet+NSObject.h from [06675274eb] to [9214bbd006].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFSet+NSObject.m from [32b967da40] to [e5bc663707].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFString+NSObject.h from [e3e9530327] to [375ab3a6b5].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/OFString+NSObject.m from [fefeea73ea] to [bf4d082579].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/bridge/ObjFWBridge.h from [2ccf4ce44e] to [1fbb08ae27].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Renamed and modified src/encodings/codepage_437.m [d62d8ff5ca] to src/encodings/codepage-437.m [1cc88f79fe].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "common.h" const OFChar16 OFCodepage437Table[] = { 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 }; const size_t OFCodepage437TableOffset = 256 - (sizeof(OFCodepage437Table) / sizeof(*OFCodepage437Table)); static const unsigned char page0[] = { 0xFF, 0xAD, 0x9B, 0x9C, 0x00, 0x9D, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xAE, 0xAA, 0x00, 0x00, 0x00, 0xF8, 0xF1, 0xFD, 0x00, 0x00, 0xE6, 0x00, 0xFA, 0x00, 0x00, 0xA7, 0xAF, 0xAC, 0xAB, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x8F, 0x92, 0x80, |
︙ | ︙ | |||
127 128 129 130 131 132 133 | 0xDE, 0xB0, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE }; static const uint8_t page25Start = 0x00; bool | | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | 0xDE, 0xB0, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE }; static const uint8_t page25Start = 0x00; bool OFUnicodeToCodepage437(const OFUnichar *input, unsigned char *output, size_t length, bool lossy) { for (size_t i = 0; i < length; i++) { OFUnichar c = input[i]; if OF_UNLIKELY (c > 0x7F) { uint8_t idx; if OF_UNLIKELY (c > 0xFFFF) { if (lossy) { output[i] = '?'; |
︙ | ︙ |
Renamed and modified src/encodings/codepage_850.m [1987cfb8b5] to src/encodings/codepage-850.m [d9cdb5c58f].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "common.h" const OFChar16 OFCodepage850Table[] = { 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 }; const size_t OFCodepage850TableOffset = 256 - (sizeof(OFCodepage850Table) / sizeof(*OFCodepage850Table)); static const unsigned char page0[] = { 0xFF, 0xAD, 0xBD, 0x9C, 0xCF, 0xBE, 0xDD, 0xF5, 0xF9, 0xB8, 0xA6, 0xAE, 0xAA, 0xF0, 0xA9, 0xEE, 0xF8, 0xF1, 0xFD, 0xFC, 0xEF, 0xE6, 0xF4, 0xFA, 0xF7, 0xFB, 0xA7, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8, |
︙ | ︙ | |||
103 104 105 106 107 108 109 | 0x00, 0xB0, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE }; static const uint8_t page25Start = 0x00; bool | | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 0x00, 0xB0, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE }; static const uint8_t page25Start = 0x00; bool OFUnicodeToCodepage850(const OFUnichar *input, unsigned char *output, size_t length, bool lossy) { for (size_t i = 0; i < length; i++) { OFUnichar c = input[i]; if OF_UNLIKELY (c > 0x7F) { uint8_t idx; if OF_UNLIKELY (c > 0xFFFF) { if (lossy) { output[i] = '?'; |
︙ | ︙ |
Renamed and modified src/encodings/codepage_858.m [076db9f46a] to src/encodings/codepage-858.m [402e5b0a14].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "common.h" const OFChar16 OFCodepage858Table[] = { 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 }; const size_t OFCodepage858TableOffset = 256 - (sizeof(OFCodepage858Table) / sizeof(*OFCodepage858Table)); static const unsigned char page0[] = { 0xFF, 0xAD, 0xBD, 0x9C, 0xCF, 0xBE, 0xDD, 0xF5, 0xF9, 0xB8, 0xA6, 0xAE, 0xAA, 0xF0, 0xA9, 0xEE, 0xF8, 0xF1, 0xFD, 0xFC, 0xEF, 0xE6, 0xF4, 0xFA, 0xF7, 0xFB, 0xA7, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8, |
︙ | ︙ | |||
109 110 111 112 113 114 115 | 0x00, 0xB0, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE }; static const uint8_t page25Start = 0x00; bool | | | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | 0x00, 0xB0, 0xB1, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE }; static const uint8_t page25Start = 0x00; bool OFUnicodeToCodepage858(const OFUnichar *input, unsigned char *output, size_t length, bool lossy) { for (size_t i = 0; i < length; i++) { OFUnichar c = input[i]; if OF_UNLIKELY (c > 0x7F) { uint8_t idx; if OF_UNLIKELY (c > 0xFFFF) { if (lossy) { output[i] = '?'; |
︙ | ︙ |
Modified src/encodings/common.h from [46b2b33ba1] to [a9b82f31be].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Renamed and modified src/encodings/iso_8859-15.m [8a992cf99b] to src/encodings/iso-8859-15.m [8197488f98].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "common.h" const OFChar16 OFISO8859_15Table[] = { 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7, 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7, 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF }; const size_t OFISO8859_15TableOffset = 256 - (sizeof(OFISO8859_15Table) / sizeof(*OFISO8859_15Table)); static const unsigned char page0[] = { 0x00, 0xA5, 0x00, 0xA7, 0x00, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0x00, 0xB5, 0xB6, 0xB7, 0x00, 0xB9, 0xBA, 0xBB, 0x00, 0x00, 0x00 }; |
︙ | ︙ | |||
58 59 60 61 62 63 64 | static const unsigned char page20[] = { 0xA4 }; static const uint8_t page20Start = 0xAC; bool | | | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | static const unsigned char page20[] = { 0xA4 }; static const uint8_t page20Start = 0xAC; bool OFUnicodeToISO8859_15(const OFUnichar *input, unsigned char *output, size_t length, bool lossy) { for (size_t i = 0; i < length; i++) { OFUnichar c = input[i]; if OF_UNLIKELY (c > 0x7F) { uint8_t idx; if OF_UNLIKELY (c > 0xFFFF) { if (lossy) { output[i] = '?'; |
︙ | ︙ |
Renamed and modified src/encodings/iso_8859-2.m [c37ad1bb56] to src/encodings/iso-8859-2.m [b10a788d3d].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "common.h" const OFChar16 OFISO8859_2Table[] = { 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 }; const size_t OFISO8859_2TableOffset = 256 - (sizeof(OFISO8859_2Table) / sizeof(*OFISO8859_2Table)); static const unsigned char page0[] = { 0xA0, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00, 0xA7, 0xA8, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0xC2, 0x00, 0xC4, 0x00, 0x00, 0xC7, |
︙ | ︙ | |||
78 79 80 81 82 83 84 | 0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xFF, 0x00, 0xB2, 0x00, 0xBD }; static const uint8_t page2Start = 0xC7; bool | | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xFF, 0x00, 0xB2, 0x00, 0xBD }; static const uint8_t page2Start = 0xC7; bool OFUnicodeToISO8859_2(const OFUnichar *input, unsigned char *output, size_t length, bool lossy) { for (size_t i = 0; i < length; i++) { OFUnichar c = input[i]; if OF_UNLIKELY (c > 0x7F) { uint8_t idx; if OF_UNLIKELY (c > 0xFFFF) { if (lossy) { output[i] = '?'; |
︙ | ︙ |
Renamed and modified src/encodings/iso_8859-3.m [5f4c6ba0f6] to src/encodings/iso-8859-3.m [57543aa317].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "common.h" const OFChar16 OFISO8859_3Table[] = { 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0xFFFF, 0x0124, 0x00A7, 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0xFFFF, 0x017B, 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0xFFFF, 0x017C, 0x00C0, 0x00C1, 0x00C2, 0xFFFF, 0x00C4, 0x010A, 0x0108, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0xFFFF, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0xFFFF, 0x00E4, 0x010B, 0x0109, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0xFFFF, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9 }; const size_t OFISO8859_3TableOffset = 256 - (sizeof(OFISO8859_3Table) / sizeof(*OFISO8859_3Table)); static const unsigned char page0[] = { 0xA0, 0x00, 0x00, 0xA3, 0xA4, 0x00, 0x00, 0xA7, 0xA8, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x00, 0xB0, 0x00, 0xB2, 0xB3, 0xB4, 0xB5, 0x00, 0xB7, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xBD, 0x00, 0x00, 0xC0, 0xC1, 0xC2, 0x00, 0xC4, 0x00, 0x00, 0xC7, |
︙ | ︙ | |||
75 76 77 78 79 80 81 | static const unsigned char page2[] = { 0xA2, 0xFF }; static const uint8_t page2Start = 0xD8; bool | | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | static const unsigned char page2[] = { 0xA2, 0xFF }; static const uint8_t page2Start = 0xD8; bool OFUnicodeToISO8859_3(const OFUnichar *input, unsigned char *output, size_t length, bool lossy) { for (size_t i = 0; i < length; i++) { OFUnichar c = input[i]; if OF_UNLIKELY (c > 0x7F) { uint8_t idx; if OF_UNLIKELY (c > 0xFFFF) { if (lossy) { output[i] = '?'; |
︙ | ︙ |
Modified src/encodings/koi8-r.m from [29498b5aa9] to [e29e1b888f].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "common.h" const OFChar16 OFKOI8RTable[] = { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590, 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248, 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7, 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E, 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9, 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A, 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A }; const size_t OFKOI8RTableOffset = 256 - (sizeof(OFKOI8RTable) / sizeof(*OFKOI8RTable)); static const unsigned char page0[] = { 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
︙ | ︙ | |||
113 114 115 116 117 118 119 | 0x8F, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94 }; static const uint8_t page25Start = 0x00; bool | | | | | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | 0x8F, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94 }; static const uint8_t page25Start = 0x00; bool OFUnicodeToKOI8R(const OFUnichar *input, unsigned char *output, size_t length, bool lossy) { for (size_t i = 0; i < length; i++) { OFUnichar c = input[i]; if OF_UNLIKELY (c > 0x7F) { uint8_t idx; if OF_UNLIKELY (c > 0xFFFF) { if (lossy) { output[i] = '?'; |
︙ | ︙ |
Modified src/encodings/koi8-u.m from [c05bd3e1cb] to [10ad0de57d].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "common.h" const OFChar16 OFKOI8UTable[] = { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590, 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248, 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7, 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x0491, 0x255D, 0x255E, 0x255F, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x0490, 0x256C, 0x00A9, 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A, 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A }; const size_t OFKOI8UTableOffset = 256 - (sizeof(OFKOI8UTable) / sizeof(*OFKOI8UTable)); static const unsigned char page0[] = { 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
︙ | ︙ | |||
121 122 123 124 125 126 127 | 0x8F, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94 }; static const uint8_t page25Start = 0x00; bool | | | | | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | 0x8F, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94 }; static const uint8_t page25Start = 0x00; bool OFUnicodeToKOI8U(const OFUnichar *input, unsigned char *output, size_t length, bool lossy) { for (size_t i = 0; i < length; i++) { OFUnichar c = input[i]; if OF_UNLIKELY (c > 0x7F) { uint8_t idx; if OF_UNLIKELY (c > 0xFFFF) { if (lossy) { output[i] = '?'; |
︙ | ︙ |
Renamed and modified src/encodings/mac_roman.m [696af3cc01] to src/encodings/mac-roman.m [5811cbe352].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "common.h" const OFChar16 OFMacRomanTable[] = { 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3, 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC, 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF, 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8, 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB, 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153, 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02, 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4, 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC, 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7 }; const size_t OFMacRomanTableOffset = 256 - (sizeof(OFMacRomanTable) / sizeof(*OFMacRomanTable)); static const unsigned char page0[] = { 0xCA, 0xC1, 0xA2, 0xA3, 0x00, 0xB4, 0x00, 0xA4, 0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0x00, 0xA8, 0xF8, 0xA1, 0xB1, 0x00, 0x00, 0xAB, 0xB5, 0xA6, 0xE1, 0xFC, 0x00, 0xBC, 0xC8, 0x00, 0x00, 0x00, 0xC0, 0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82, |
︙ | ︙ | |||
147 148 149 150 151 152 153 | static const unsigned char pageFB[] = { 0xDE, 0xDF }; static const uint8_t pageFBStart = 0x01; bool | | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | static const unsigned char pageFB[] = { 0xDE, 0xDF }; static const uint8_t pageFBStart = 0x01; bool OFUnicodeToMacRoman(const OFUnichar *input, unsigned char *output, size_t length, bool lossy) { for (size_t i = 0; i < length; i++) { OFUnichar c = input[i]; if OF_UNLIKELY (c > 0x7F) { uint8_t idx; if OF_UNLIKELY (c > 0xFFFF) { if (lossy) { output[i] = '?'; |
︙ | ︙ |
Modified src/encodings/windows-1251.m from [18ae3df621] to [b8c4870fa7].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "common.h" const OFChar16 OFWindows1251Table[] = { 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0xFFFF, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F, 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7, 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F }; const size_t OFWindows1251TableOffset = 256 - (sizeof(OFWindows1251Table) / sizeof(*OFWindows1251Table)); static const unsigned char page0[] = { 0xA0, 0x00, 0x00, 0x00, 0xA4, 0x00, 0xA6, 0xA7, 0x00, 0xA9, 0x00, 0xAB, 0xAC, 0xAD, 0xAE, 0x00, 0xB0, 0xB1, 0x00, 0x00, 0x00, 0xB5, 0xB6, 0xB7, 0x00, 0x00, 0x00, 0xBB }; |
︙ | ︙ | |||
100 101 102 103 104 105 106 | static const unsigned char page21[] = { 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99 }; static const uint8_t page21Start = 0x16; bool | | | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | static const unsigned char page21[] = { 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99 }; static const uint8_t page21Start = 0x16; bool OFUnicodeToWindows1251(const OFUnichar *input, unsigned char *output, size_t length, bool lossy) { for (size_t i = 0; i < length; i++) { OFUnichar c = input[i]; if OF_UNLIKELY (c > 0x7F) { uint8_t idx; if OF_UNLIKELY (c > 0xFFFF) { if (lossy) { output[i] = '?'; |
︙ | ︙ |
Modified src/encodings/windows-1252.m from [792d858e21] to [f9fc8b9676].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" #import "common.h" const OFChar16 OFWindows1252Table[] = { 0x20AC, 0xFFFF, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFF, 0x017D, 0xFFFF, 0xFFFF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFF, 0x017E, 0x0178, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF }; const size_t OFWindows1252TableOffset = 256 - (sizeof(OFWindows1252Table) / sizeof(*OFWindows1252Table)); static const unsigned char page0[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
︙ | ︙ | |||
96 97 98 99 100 101 102 | static const unsigned char page21[] = { 0x99 }; static const uint8_t page21Start = 0x22; bool | | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | static const unsigned char page21[] = { 0x99 }; static const uint8_t page21Start = 0x22; bool OFUnicodeToWindows1252(const OFUnichar *input, unsigned char *output, size_t length, bool lossy) { for (size_t i = 0; i < length; i++) { OFUnichar c = input[i]; if OF_UNLIKELY (c > 0x7F) { uint8_t idx; if OF_UNLIKELY (c > 0xFFFF) { if (lossy) { output[i] = '?'; |
︙ | ︙ |
Modified src/exceptions/Makefile from [103a175ba6] to [edffb84129].
︙ | ︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | OFCopyItemFailedException.m \ OFCreateDirectoryFailedException.m \ OFCreateSymbolicLinkFailedException.m \ OFEnumerationMutationException.m \ OFException.m \ OFGetOptionFailedException.m \ OFHashAlreadyCalculatedException.m \ OFInitializationFailedException.m \ OFInvalidArgumentException.m \ OFInvalidEncodingException.m \ OFInvalidFormatException.m \ OFInvalidJSONException.m \ OFInvalidServerReplyException.m \ OFLinkFailedException.m \ OFLockFailedException.m \ OFMalformedXMLException.m \ | > < < | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | OFCopyItemFailedException.m \ OFCreateDirectoryFailedException.m \ OFCreateSymbolicLinkFailedException.m \ OFEnumerationMutationException.m \ OFException.m \ OFGetOptionFailedException.m \ OFHashAlreadyCalculatedException.m \ OFHashNotCalculatedException.m \ OFInitializationFailedException.m \ OFInvalidArgumentException.m \ OFInvalidEncodingException.m \ OFInvalidFormatException.m \ OFInvalidJSONException.m \ OFInvalidServerReplyException.m \ OFLinkFailedException.m \ OFLockFailedException.m \ OFMalformedXMLException.m \ OFMoveItemFailedException.m \ OFNotImplementedException.m \ OFNotOpenException.m \ OFOpenItemFailedException.m \ OFOutOfMemoryException.m \ OFOutOfRangeException.m \ OFReadFailedException.m \ OFReadOrWriteFailedException.m \ OFRemoveItemFailedException.m \ OFRetrieveItemAttributesFailedException.m \ OFSeekFailedException.m \ OFSetItemAttributesFailedException.m \ OFSetOptionFailedException.m \ OFStillLockedException.m \ OFTruncatedDataException.m \ OFUnboundNamespaceException.m \ OFUnboundPrefixException.m \ |
︙ | ︙ | |||
58 59 60 61 62 63 64 | OFAlreadyConnectedException.m \ OFBindFailedException.m \ OFConnectionFailedException.m \ OFDNSQueryFailedException.m \ OFHTTPRequestFailedException.m \ OFListenFailedException.m \ OFObserveFailedException.m \ | | > | > > | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | OFAlreadyConnectedException.m \ OFBindFailedException.m \ OFConnectionFailedException.m \ OFDNSQueryFailedException.m \ OFHTTPRequestFailedException.m \ OFListenFailedException.m \ OFObserveFailedException.m \ OFResolveHostFailedException.m \ OFTLSHandshakeFailedException.m SRCS_THREADS = OFConditionBroadcastFailedException.m \ OFConditionSignalFailedException.m \ OFConditionStillWaitingException.m \ OFConditionWaitFailedException.m \ OFThreadJoinFailedException.m \ OFThreadStartFailedException.m \ OFThreadStillRunningException.m SRCS_WINDOWS = OFCreateWindowsRegistryKeyFailedException.m \ OFDeleteWindowsRegistryKeyFailedException.m \ OFDeleteWindowsRegistryValueFailedException.m \ OFGetWindowsRegistryValueFailedException.m \ OFOpenWindowsRegistryKeyFailedException.m \ OFSetWindowsRegistryValueFailedException.m INCLUDES := ${SRCS:.m=.h} SRCS += OFSandboxActivationFailedException.m include ../../buildsys.mk CPPFLAGS += -I. -I.. -I../.. -I../runtime |
Modified src/exceptions/OFAcceptFailedException.h from [07a2f9d03f] to [257583a910].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
50 51 52 53 54 55 56 | /** * @brief Creates a new, autoreleased accept failed exception. * * @param socket The socket which could not accept a connection * @param errNo The errno for the error * @return A new, autoreleased accept failed exception */ | | < | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /** * @brief Creates a new, autoreleased accept failed exception. * * @param socket The socket which could not accept a connection * @param errNo The errno for the error * @return A new, autoreleased accept failed exception */ + (instancetype)exceptionWithSocket: (id)socket errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated accept failed exception. * * @param socket The socket which could not accept a connection |
︙ | ︙ |
Modified src/exceptions/OFAcceptFailedException.m from [a59ffc8d01] to [8a127340d9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | @synthesize socket = _socket, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } | | < | < | < | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | @synthesize socket = _socket, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithSocket: (id)socket errNo: (int)errNo { return [[[self alloc] initWithSocket: socket errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithSocket: (id)socket errNo: (int)errNo { self = [super init]; _socket = [socket retain]; _errNo = errNo; return self; } - (void)dealloc { [_socket release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to accept connection in socket of class %@: %@", [_socket class], OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFAllocFailedException.h from [0364422b9e] to [89360977c8].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFAllocFailedException.m from [54ff75e246] to [845ed2917e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
32 33 34 35 36 37 38 | } - (instancetype)init { OF_INVALID_INIT_METHOD } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)retain { return self; } - (instancetype)autorelease { return self; } - (unsigned int)retainCount { return OFMaxRetainCount; } - (void)release { } - (void)dealloc |
︙ | ︙ |
Modified src/exceptions/OFAlreadyConnectedException.h from [e56b6041c7] to [56f0934858].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFAlreadyConnectedException.m from [74939bf32e] to [055eee0622].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFBindFailedException.h from [c5dc0bbbc4] to [5fb5dee342].
1 | /* | < < | | < | > > > | > > > > > < < > > > > > > > > > > | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFException.h" #ifndef OF_HAVE_SOCKETS # error No sockets available! #endif #import "OFSocket.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFBindFailedException \ * OFBindFailedException.h ObjFW/OFBindFailedException.h * * @brief An exception indicating that binding a socket failed. */ @interface OFBindFailedException: OFException { /* IP */ OFString *_Nullable _host; uint16_t _port; /* IPX */ uint8_t _packetType; /* UNIX socket */ OFString *_Nullable _path; id _socket; int _errNo; } /** * @brief The host on which binding failed. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *host; /** * @brief The port on which binding failed. */ @property (readonly, nonatomic) uint16_t port; /** * @brief The IPX packet type for which binding failed. */ @property (readonly, nonatomic) uint8_t packetType; /** * @brief The path on which binding failed. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *path; /** * @brief The socket which could not be bound. */ @property (readonly, nonatomic) id socket; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased bind failed exception. * * @param host The host on which binding failed * @param port The port on which binding failed * @param socket The socket which could not be bound * @param errNo The errno of the error that occurred * @return A new, autoreleased bind failed exception */ + (instancetype)exceptionWithHost: (OFString *)host port: (uint16_t)port socket: (id)socket errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Creates a new, autoreleased bind failed exception. * * @param port The IPX port to which binding failed * @param packetType The IPX packet type for which binding failed * @param socket The socket which could not be bound * @param errNo The errno of the error that occurred * @return A new, autoreleased bind failed exception */ + (instancetype)exceptionWithPort: (uint16_t)port packetType: (uint8_t)packetType socket: (id)socket errNo: (int)errNo; /** * @brief Creates a new, autoreleased bind failed exception. * * @param path The path on which binding failed * @param socket The socket which could not be bound * @param errNo The errno of the error that occurred * @return A new, autoreleased bind failed exception */ + (instancetype)exceptionWithPath: (OFString *)path socket: (id)socket errNo: (int)errNo; /** * @brief Initializes an already allocated bind failed exception. * * @param host The host on which binding failed * @param port The port on which binding failed * @param socket The socket which could not be bound |
︙ | ︙ | |||
122 123 124 125 126 127 128 129 130 131 | * @param errNo The errno of the error that occurred * @return An initialized bind failed exception */ - (instancetype)initWithPort: (uint16_t)port packetType: (uint8_t)packetType socket: (id)socket errNo: (int)errNo; @end OF_ASSUME_NONNULL_END | > > > > > > > > > > > > > | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | * @param errNo The errno of the error that occurred * @return An initialized bind failed exception */ - (instancetype)initWithPort: (uint16_t)port packetType: (uint8_t)packetType socket: (id)socket errNo: (int)errNo; /** * @brief Initializes an already allocated bind failed exception. * * @param path The path on which binding failed * @param socket The socket which could not be bound * @param errNo The errno of the error that occurred * @return An initialized bind failed exception */ - (instancetype)initWithPath: (OFString *)path socket: (id)socket errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFBindFailedException.m from [66d49adee0] to [0fa4a1273c].
1 | /* | < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFBindFailedException.h" #import "OFString.h" @implementation OFBindFailedException @synthesize host = _host, port = _port, packetType = _packetType, path = _path; @synthesize socket = _socket, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } |
︙ | ︙ | |||
46 47 48 49 50 51 52 53 54 55 56 57 58 59 | errNo: (int)errNo { return [[[self alloc] initWithPort: port packetType: packetType socket: sock errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithHost: (OFString *)host | > > > > > > > > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | errNo: (int)errNo { return [[[self alloc] initWithPort: port packetType: packetType socket: sock errNo: errNo] autorelease]; } + (instancetype)exceptionWithPath: (OFString *)path socket: (id)sock errNo: (int)errNo { return [[[self alloc] initWithPath: path socket: sock errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithHost: (OFString *)host |
︙ | ︙ | |||
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_host release]; [_socket release]; [super dealloc]; } - (OFString *)description { | > > > > > > > > > > > > > > > > > > > > > > > | | | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithPath: (OFString *)path socket: (id)sock errNo: (int)errNo { self = [super init]; @try { _path = [path copy]; _socket = [sock retain]; _errNo = errNo; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_host release]; [_path release]; [_socket release]; [super dealloc]; } - (OFString *)description { if (_path != nil) return [OFString stringWithFormat: @"Binding to path %@ failed in socket of type %@: %@", _path, [_socket class], OFStrError(_errNo)]; else if (_host != nil) return [OFString stringWithFormat: @"Binding to port %" @PRIu16 @" on host %@ failed in " @"socket of type %@: %@", _port, _host, [_socket class], OFStrError(_errNo)]; else return [OFString stringWithFormat: @"Binding to port %" @PRIx16 @" for packet type %" @PRIx8 @" failed in socket of type %@: %@", _port, _packetType, [_socket class], OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFChangeCurrentDirectoryPathFailedException.h from [32789dc600] to [fce19a8f8b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
40 41 42 43 44 45 46 | @property (readonly, nonatomic) OFString *path; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | < | > > | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | @property (readonly, nonatomic) OFString *path; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased change current directory path failed * exception. * * @param path The path of the directory to which the current path could not be * changed * @param errNo The errno of the error that occurred * @return A new, autoreleased change current directory path failed exception */ + (instancetype)exceptionWithPath: (OFString *)path errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated change directory failed exception. * * @param path The path of the directory to which the current path could not be * changed * @param errNo The errno of the error that occurred * @return An initialized change current directory path failed exception */ - (instancetype)initWithPath: (OFString *)path errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFChangeCurrentDirectoryPathFailedException.m from [2ba63a593c] to [35ec7fdb32].
1 | /* | < < | > > > > > < < < < < < < < < < < < | < > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFChangeCurrentDirectoryPathFailedException.h" #import "OFString.h" @implementation OFChangeCurrentDirectoryPathFailedException @synthesize path = _path, errNo = _errNo; + (instancetype)exceptionWithPath: (OFString *)path errNo: (int)errNo { return [[[self alloc] initWithPath: path errNo: errNo] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithPath: (OFString *)path errNo: (int)errNo { self = [super init]; @try { _path = [path copy]; _errNo = errNo; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_path release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to change the current directory path to %@: %@", _path, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFChecksumMismatchException.h from [608c4452e2] to [e6f142cd8f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFChecksumMismatchException.m from [d1823bdb3b] to [194677cc27].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFConditionBroadcastFailedException.h from [5078c9d198] to [d2d182c69d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | OFCondition *_condition; int _errNo; } /** * @brief The condition which could not be broadcasted. */ | | | > > | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | OFCondition *_condition; int _errNo; } /** * @brief The condition which could not be broadcasted. */ @property (readonly, nonatomic) OFCondition *condition; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Returns a new, autoreleased condition broadcast failed exception. * * @param condition The condition which could not be broadcasted * @param errNo The errno of the error that occurred * @return A new, autoreleased condition broadcast failed exception */ + (instancetype)exceptionWithCondition: (OFCondition *)condition errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated condition broadcast failed exception. * * @param condition The condition which could not be broadcasted * @param errNo The errno of the error that occurred * @return An initialized condition broadcast failed exception */ - (instancetype)initWithCondition: (OFCondition *)condition errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFConditionBroadcastFailedException.m from [150053cff3] to [0c18d20911].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | + (instancetype)exceptionWithCondition: (OFCondition *)condition errNo: (int)errNo { return [[[self alloc] initWithCondition: condition errNo: errNo] autorelease]; } | > > > > > | < | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | + (instancetype)exceptionWithCondition: (OFCondition *)condition errNo: (int)errNo { return [[[self alloc] initWithCondition: condition errNo: errNo] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithCondition: (OFCondition *)condition errNo: (int)errNo { self = [super init]; _condition = [condition retain]; _errNo = errNo; return self; |
︙ | ︙ |
Modified src/exceptions/OFConditionSignalFailedException.h from [22eaf3ab3a] to [92e2796a89].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | OFCondition *_condition; int _errNo; } /** * @brief The condition which could not be signaled. */ | | | > > | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | OFCondition *_condition; int _errNo; } /** * @brief The condition which could not be signaled. */ @property (readonly, nonatomic) OFCondition *condition; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased condition signal failed exception. * * @param condition The condition which could not be signaled * @param errNo The errno of the error that occurred * @return A new, autoreleased condition signal failed exception */ + (instancetype)exceptionWithCondition: (OFCondition *)condition errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated condition signal failed exception. * * @param condition The condition which could not be signaled * @param errNo The errno of the error that occurred * @return An initialized condition signal failed exception */ - (instancetype)initWithCondition: (OFCondition *)condition errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFConditionSignalFailedException.m from [6f920729b9] to [7b1b56675f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | + (instancetype)exceptionWithCondition: (OFCondition *)condition errNo: (int)errNo { return [[[self alloc] initWithCondition: condition errNo: errNo] autorelease]; } | > > > > > | < | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | + (instancetype)exceptionWithCondition: (OFCondition *)condition errNo: (int)errNo { return [[[self alloc] initWithCondition: condition errNo: errNo] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithCondition: (OFCondition *)condition errNo: (int)errNo { self = [super init]; _condition = [condition retain]; _errNo = errNo; return self; |
︙ | ︙ |
Modified src/exceptions/OFConditionStillWaitingException.h from [c466091667] to [63592271b5].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | { OFCondition *_condition; } /** * @brief The condition for which is still being waited. */ | | | > > | > > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | { OFCondition *_condition; } /** * @brief The condition for which is still being waited. */ @property (readonly, nonatomic) OFCondition *condition; /** * @brief Creates a new, autoreleased condition still waiting exception. * * @param condition The condition for which is still being waited * @return A new, autoreleased condition still waiting exception */ + (instancetype)exceptionWithCondition: (OFCondition *)condition; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated condition still waiting exception. * * @param condition The condition for which is still being waited * @return An initialized condition still waiting exception */ - (instancetype)initWithCondition: (OFCondition *)condition OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFConditionStillWaitingException.m from [607c9157ff] to [28d38d170f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | @synthesize condition = _condition; + (instancetype)exceptionWithCondition: (OFCondition *)condition { return [[[self alloc] initWithCondition: condition] autorelease]; } | | | > > > > > < | | | | < < < | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | @synthesize condition = _condition; + (instancetype)exceptionWithCondition: (OFCondition *)condition { return [[[self alloc] initWithCondition: condition] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithCondition: (OFCondition *)condition { self = [super init]; _condition = [condition retain]; return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_condition release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Deallocation of a condition of type %@ was tried, even though " "a thread was still waiting for it!", _condition.class]; } @end |
Modified src/exceptions/OFConditionWaitFailedException.h from [f1a62ef0f5] to [4c780f1cdc].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | OFCondition *_condition; int _errNo; } /** * @brief The condition for which could not be waited. */ | | | > > | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | OFCondition *_condition; int _errNo; } /** * @brief The condition for which could not be waited. */ @property (readonly, nonatomic) OFCondition *condition; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased condition wait failed exception. * * @param condition The condition for which could not be waited * @param errNo The errno of the error that occurred * @return A new, autoreleased condition wait failed exception */ + (instancetype)exceptionWithCondition: (OFCondition *)condition errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated condition wait failed exception. * * @param condition The condition for which could not be waited * @param errNo The errno of the error that occurred * @return An initialized condition wait failed exception */ - (instancetype)initWithCondition: (OFCondition *)condition errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFConditionWaitFailedException.m from [3628b82a85] to [5702b9d98a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | + (instancetype)exceptionWithCondition: (OFCondition *)condition errNo: (int)errNo { return [[[self alloc] initWithCondition: condition errNo: errNo] autorelease]; } | > > > > > | < | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | + (instancetype)exceptionWithCondition: (OFCondition *)condition errNo: (int)errNo { return [[[self alloc] initWithCondition: condition errNo: errNo] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithCondition: (OFCondition *)condition errNo: (int)errNo { self = [super init]; _condition = [condition retain]; _errNo = errNo; return self; |
︙ | ︙ |
Modified src/exceptions/OFConnectionFailedException.h from [2ceab3ca9f] to [2687b6eb31].
1 | /* | < < | | < | > > < < < < < > > > > > > > > > > < < | > > > > > > > > > > > > | | > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFException.h" #ifndef OF_HAVE_SOCKETS # error No sockets available! #endif #import "OFSocket.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFConnectionFailedException \ * OFConnectionFailedException.h ObjFW/OFConnectionFailedException.h * * @brief An exception indicating that a connection could not be established. */ @interface OFConnectionFailedException: OFException { OFString *_Nullable _host; uint16_t _port; unsigned char _node[IPX_NODE_LEN]; uint32_t _network; OFString *_Nullable _path; id _socket; int _errNo; } /** * @brief The host to which the connection failed. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *host; /** * @brief The port on the host to which the connection failed. */ @property (readonly, nonatomic) uint16_t port; /** * @brief The IPX node to which the connection failed. */ @property (readonly, nonatomic) unsigned char *node; /** * @brief The IPX network of the node to which the connection failed. */ @property (readonly, nonatomic) uint32_t network; /** * @brief The path to which the connection failed. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *path; /** * @brief The socket which could not connect. */ @property (readonly, nonatomic) id socket; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased connection failed exception. * * @param host The host to which the connection failed * @param port The port on the host to which the connection failed * @param socket The socket which could not connect * @param errNo The errno of the error that occurred * @return A new, autoreleased connection failed exception */ + (instancetype)exceptionWithHost: (OFString *)host port: (uint16_t)port socket: (id)socket errNo: (int)errNo; /** * @brief Creates a new, autoreleased connection failed exception. * * @param node The node to which the connection failed * @param network The IPX network of the node to which the connection failed * @param port The port on the node to which the connection failed * @param socket The socket which could not connect * @param errNo The errno of the error that occurred * @return A new, autoreleased connection failed exception */ + (instancetype)exceptionWithNode: (unsigned char [_Nullable IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port socket: (id)socket errNo: (int)errNo; /** * @brief Creates a new, autoreleased connection failed exception. * * @param path The path to which the connection failed * @param socket The socket which could not connect * @param errNo The errno of the error that occurred * @return A new, autoreleased connection failed exception */ + (instancetype)exceptionWithPath: (OFString *)path socket: (id)socket errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated connection failed exception. * * @param host The host to which the connection failed * @param port The port on the host to which the connection failed * @param socket The socket which could not connect * @param errNo The errno of the error that occurred * @return An initialized connection failed exception */ - (instancetype)initWithHost: (OFString *)host port: (uint16_t)port socket: (id)socket errNo: (int)errNo; /** * @brief Initializes an already allocated connection failed exception. * * @param node The node to which the connection failed * @param network The IPX network of the node to which the connection failed * @param port The port on the node to which the connection failed * @param socket The socket which could not connect * @param errNo The errno of the error that occurred * @return An initialized connection failed exception */ - (instancetype)initWithNode: (unsigned char [_Nullable IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port socket: (id)socket errNo: (int)errNo; /** * @brief Initializes an already allocated connection failed exception. * * @param path The path to which the connection failed * @param socket The socket which could not connect * @param errNo The errno of the error that occurred * @return An initialized connection failed exception */ - (instancetype)initWithPath: (OFString *)path socket: (id)socket errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFConnectionFailedException.m from [7c382ce8cb] to [1671ca3ac8].
1 | /* | < < | | | < < < < < > > > > > | > > < > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFConnectionFailedException.h" #import "OFString.h" @implementation OFConnectionFailedException @synthesize host = _host, port = _port, network = _network, path = _path; @synthesize socket = _socket, errNo = _errNo; + (instancetype)exceptionWithHost: (OFString *)host port: (uint16_t)port socket: (id)sock errNo: (int)errNo { return [[[self alloc] initWithHost: host port: port socket: sock errNo: errNo] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithNode: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port socket: (id)sock errNo: (int)errNo { return [[[self alloc] initWithNode: node network: network port: port socket: sock errNo: errNo] autorelease]; } + (instancetype)exceptionWithPath: (OFString *)path socket: (id)sock errNo: (int)errNo { return [[[self alloc] initWithPath: path socket: sock errNo: errNo] autorelease]; } - (instancetype)initWithHost: (OFString *)host port: (uint16_t)port socket: (id)sock errNo: (int)errNo { |
︙ | ︙ | |||
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_host release]; [_socket release]; [super dealloc]; } - (unsigned char *)node { return _node; } - (OFString *)description { | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithPath: (OFString *)path socket: (id)sock errNo: (int)errNo { self = [super init]; @try { _path = [path copy]; _socket = [sock retain]; _errNo = errNo; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_host release]; [_path release]; [_socket release]; [super dealloc]; } - (unsigned char *)node { return _node; } - (OFString *)description { if (_path != nil) return [OFString stringWithFormat: @"A connection to %@ could not be established in socket of " @"type %@: %@", _path, [_socket class], OFStrError(_errNo)]; else if (_host != nil) return [OFString stringWithFormat: @"A connection to %@ on port %" @PRIu16 @" could not be " @"established in socket of type %@: %@", _host, _port, [_socket class], OFStrError(_errNo)]; else if (memcmp(_node, "\0\0\0\0\0", IPX_NODE_LEN) == 0) return [OFString stringWithFormat: @"A connection to %02X%02X%02X%02X%02X%02X port %" @PRIu16 @" on network %" @PRIX32 " could not be established in " @"socket of type %@: %@", _node[0], _node[1], _node[2], _node[3], _node[4], _node[5], _port, _network, [_socket class], OFStrError(_errNo)]; else return [OFString stringWithFormat: @"A connection could not be established in socket of " @"type %@: %@", [_socket class], OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFCopyItemFailedException.h from [a609d68d24] to [6dbfc6ae6a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | @interface OFCopyItemFailedException: OFException { OFURL *_sourceURL, *_destinationURL; int _errNo; } /** | | | < < | | | | | > > | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | @interface OFCopyItemFailedException: OFException { OFURL *_sourceURL, *_destinationURL; int _errNo; } /** * @brief The URL of the source item. */ @property (readonly, nonatomic) OFURL *sourceURL; /** * @brief The destination URL. */ @property (readonly, nonatomic) OFURL *destinationURL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased copy item failed exception. * * @param sourceURL The URL of the source item * @param destinationURL The destination URL * @param errNo The errno of the error that occurred * @return A new, autoreleased copy item failed exception */ + (instancetype)exceptionWithSourceURL: (OFURL *)sourceURL destinationURL: (OFURL *)destinationURL errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated copy item failed exception. * * @param sourceURL The URL of the source item * @param destinationURL The destination URL * @param errNo The errno of the error that occurred * @return An initialized copy item failed exception */ - (instancetype)initWithSourceURL: (OFURL *)sourceURL destinationURL: (OFURL *)destinationURL errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFCopyItemFailedException.m from [1ccbb5f239] to [db6f54b209].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
69 70 71 72 73 74 75 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to copy item %@ to %@: %@", | | | 67 68 69 70 71 72 73 74 75 76 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to copy item %@ to %@: %@", _sourceURL, _destinationURL, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFCreateDirectoryFailedException.h from [f56bfddfea] to [9fb2f6c383].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
40 41 42 43 44 45 46 | @property (readonly, nonatomic) OFURL *URL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | < | > > | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | @property (readonly, nonatomic) OFURL *URL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased create directory failed exception. * * @param URL The URL of the directory which could not be created * @param errNo The errno of the error that occurred * @return A new, autoreleased create directory failed exception */ + (instancetype)exceptionWithURL: (OFURL *)URL errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated create directory failed exception. * * @param URL The URL of the directory which could not be created * @param errNo The errno of the error that occurred * @return An initialized create directory failed exception */ - (instancetype)initWithURL: (OFURL *)URL errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFCreateDirectoryFailedException.m from [d8d7921ecb] to [c77cc11072].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | @synthesize URL = _URL, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } | | < | < | < | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | @synthesize URL = _URL, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithURL: (OFURL *)URL errNo: (int)errNo { return [[[self alloc] initWithURL: URL errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithURL: (OFURL *)URL errNo: (int)errNo { self = [super init]; @try { _URL = [URL copy]; _errNo = errNo; } @catch (id e) { |
︙ | ︙ | |||
63 64 65 66 67 68 69 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: | | | 58 59 60 61 62 63 64 65 66 67 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to create directory %@: %@", _URL, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFCreateSymbolicLinkFailedException.h from [15f0d4bcc2] to [3600a35794].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
46 47 48 49 50 51 52 | @property (readonly, nonatomic) OFString *target; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | @property (readonly, nonatomic) OFString *target; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased create symbolic link failed exception. * * @param URL The URL where the symlink should have been created * @param target The target for the symbolic link * @param errNo The errno of the error that occurred * @return A new, autoreleased create symbolic link failed exception */ + (instancetype)exceptionWithURL: (OFURL *)URL target: (OFString *)target errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated create symbolic link failed * exception. * * @param URL The URL where the symlink should have been created * @param target The target for the symbolic link * @param errNo The errno of the error that occurred * @return An initialized create symbolic link failed exception */ - (instancetype)initWithURL: (OFURL *)URL target: (OFString *)target errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFCreateSymbolicLinkFailedException.m from [389fe64f93] to [98cc87f63e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
69 70 71 72 73 74 75 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to create symbolic link %@ with target %@: %@", | | | 67 68 69 70 71 72 73 74 75 76 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to create symbolic link %@ with target %@: %@", _URL, _target, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFCreateWindowsRegistryKeyFailedException.h from [28fcec9697] to [f321fddf5e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFCreateWindowsRegistryKeyFailedException.m from [e837a7effd] to [661d98b08e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
78 79 80 81 82 83 84 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to create subkey at path %@: %@", | | | 76 77 78 79 80 81 82 83 84 85 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to create subkey at path %@: %@", _path, OFWindowsStatusToString(_status)]; } @end |
Modified src/exceptions/OFDNSQueryFailedException.h from [a096665706] to [852291054a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | * OFDNSQueryFailedException.h ObjFW/OFDNSQueryFailedException.h * * @brief An exception indicating that a DNS query failed. */ @interface OFDNSQueryFailedException: OFException { OFDNSQuery *_query; | | | | | > | > | > | > | > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | * OFDNSQueryFailedException.h ObjFW/OFDNSQueryFailedException.h * * @brief An exception indicating that a DNS query failed. */ @interface OFDNSQueryFailedException: OFException { OFDNSQuery *_query; OFDNSResolverErrorCode _errorCode; } /** * @brief The query which could not be performed. */ @property (readonly, nonatomic) OFDNSQuery *query; /** * @brief The error code from the resolver. */ @property (readonly, nonatomic) OFDNSResolverErrorCode errorCode; /** * @brief Creates a new, autoreleased DNS query failed exception. * * @param query The query which could not be performed * @param errorCode The error from the resolver * @return A new, autoreleased address translation failed exception */ + (instancetype)exceptionWithQuery: (OFDNSQuery *)query errorCode: (OFDNSResolverErrorCode)errorCode; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated DNS query failed exception. * * @param query The query which could not be performed * @param errorCode The error from the resolver * @return An initialized address translation failed exception */ - (instancetype)initWithQuery: (OFDNSQuery *)query errorCode: (OFDNSResolverErrorCode)errorCode; - (instancetype)init OF_UNAVAILABLE; @end #ifdef __cplusplus extern "C" { #endif extern OFString *OFDNSResolverErrorCodeDescription( OFDNSResolverErrorCode errorCode); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFDNSQueryFailedException.m from [1f9661bb22] to [d34eb3c9de].
1 | /* | < < | | | | | | | | | | | | | | | > > > > > | | > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFDNSQueryFailedException.h" #import "OFString.h" OFString * OFDNSResolverErrorCodeDescription(OFDNSResolverErrorCode errorCode) { switch (errorCode) { case OFDNSResolverErrorCodeTimeout: return @"The query timed out."; case OFDNSResolverErrorCodeCanceled: return @"The query was canceled."; case OFDNSResolverErrorCodeNoResult: return @"No result for the specified host with the specified " @"type and class."; case OFDNSResolverErrorCodeServerInvalidFormat: return @"The server considered the query to be malformed."; case OFDNSResolverErrorCodeServerFailure: return @"The server was unable to process due to an internal " @"error."; case OFDNSResolverErrorCodeServerNameError: return @"The server returned an error that the domain does not " @"exist."; case OFDNSResolverErrorCodeServerNotImplemented: return @"The server does not have support for the requested " @"query."; case OFDNSResolverErrorCodeServerRefused: return @"The server refused the query."; case OFDNSResolverErrorCodeNoNameServer: return @"There was no name server to query."; default: return @"Unknown error."; } } @implementation OFDNSQueryFailedException @synthesize query = _query, errorCode = _errorCode; + (instancetype)exceptionWithQuery: (OFDNSQuery *)query errorCode: (OFDNSResolverErrorCode)errorCode { return [[[self alloc] initWithQuery: query errorCode: errorCode] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithQuery: (OFDNSQuery *)query errorCode: (OFDNSResolverErrorCode)errorCode { self = [super init]; @try { _query = [query copy]; _errorCode = errorCode; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_query release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"DNS query %@ could not be performed: %@", _query, OFDNSResolverErrorCodeDescription(_errorCode)]; } @end |
Modified src/exceptions/OFDeleteWindowsRegistryKeyFailedException.h from [eaf8e19b26] to [ce80a5fb98].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFDeleteWindowsRegistryKeyFailedException.m from [f1fda05f5e] to [123f06f5d8].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
65 66 67 68 69 70 71 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to delete subkey at path %@: %@", | | | 63 64 65 66 67 68 69 70 71 72 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to delete subkey at path %@: %@", _subkeyPath, OFWindowsStatusToString(_status)]; } @end |
Modified src/exceptions/OFDeleteWindowsRegistryValueFailedException.h from [c653480630] to [fb187a24ce].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | * ObjFW/OFDeleteWindowsRegistryValueFailedException.h * * @brief An exception indicating that deleting a Windows registry value failed. */ @interface OFDeleteWindowsRegistryValueFailedException: OFException { OFWindowsRegistryKey *_registryKey; | | | | | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | * ObjFW/OFDeleteWindowsRegistryValueFailedException.h * * @brief An exception indicating that deleting a Windows registry value failed. */ @interface OFDeleteWindowsRegistryValueFailedException: OFException { OFWindowsRegistryKey *_registryKey; OFString *_Nullable _valueName; LSTATUS _status; } /** * @brief The registry key on which deleting the value failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; /** * @brief The name of the value which could not be deleted. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *valueName; /** * @brief The status returned by RegDeleteValueEx(). */ @property (readonly, nonatomic) LSTATUS status; /** * @brief Creates a new, autoreleased delete Windows registry value failed * exception. * * @param registryKey The registry key on which deleting the value failed * @param valueName The name of the value which could not be deleted * @param status The status returned by RegDeleteValueEx() * @return A new, autoreleased delete Windows registry value failed exception */ + (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (nullable OFString *)valueName status: (LSTATUS)status; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated delete Windows registry value failed * exception. * * @param registryKey The registry key on which deleting the value failed * @param valueName The name of the value which could not be deleted * @param status The status returned by RegDeleteValueEx() * @return An initialized delete Windows registry value failed exception */ - (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (nullable OFString *)valueName status: (LSTATUS)status OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFDeleteWindowsRegistryValueFailedException.m from [9322794e56] to [efa255c388].
1 | /* | < < | | > | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFDeleteWindowsRegistryValueFailedException.h" #import "OFData.h" @implementation OFDeleteWindowsRegistryValueFailedException @synthesize registryKey = _registryKey, valueName = _valueName; @synthesize status = _status; + (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (OFString *)valueName status: (LSTATUS)status { return [[[self alloc] initWithRegistryKey: registryKey valueName: valueName status: status] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (OFString *)valueName status: (LSTATUS)status { self = [super init]; @try { _registryKey = [registryKey retain]; _valueName = [valueName copy]; _status = status; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_registryKey release]; [_valueName release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to delete value named %@: %@", _valueName, OFWindowsStatusToString(_status)]; } @end |
Modified src/exceptions/OFEnumerationMutationException.h from [86686cd9d1] to [2ab98f2cf4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
33 34 35 36 37 38 39 | } /** * @brief The object which was mutated during enumeration. */ @property (readonly, nonatomic) id object; | < < | > > | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | } /** * @brief The object which was mutated during enumeration. */ @property (readonly, nonatomic) id object; /** * @brief Creates a new, autoreleased enumeration mutation exception. * * @param object The object which was mutated during enumeration * @return A new, autoreleased enumeration mutation exception */ + (instancetype)exceptionWithObject: (id)object; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated enumeration mutation exception. * * @param object The object which was mutated during enumeration * @return An initialized enumeration mutation exception */ - (instancetype)initWithObject: (id)object OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFEnumerationMutationException.m from [7fc716b283] to [f408c0df64].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFException.h from [9ead1c434e] to [e8334cf8f9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFString; | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFString; #define OFBacktraceSize 16 #if defined(OF_WINDOWS) && defined(OF_HAVE_SOCKETS) # ifndef EADDRINUSE # define EADDRINUSE WSAEADDRINUSE # endif # ifndef EADDRNOTAVAIL # define EADDRNOTAVAIL WSAEADDRNOTAVAIL |
︙ | ︙ | |||
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | # define EUSERS WSAEUSERS # endif # ifndef EWOULDBLOCK # define EWOULDBLOCK WSAEWOULDBLOCK # endif #endif /** * @class OFException OFException.h ObjFW/OFException.h * * @brief The base class for all exceptions in ObjFW * * The OFException class is the base class for all exceptions in ObjFW, except * the OFAllocFailedException. */ @interface OFException: OFObject { | > > > > | | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | # define EUSERS WSAEUSERS # endif # ifndef EWOULDBLOCK # define EWOULDBLOCK WSAEWOULDBLOCK # endif #endif #ifndef EWOULDBLOCK # define EWOULDBLOCK EAGAIN #endif /** * @class OFException OFException.h ObjFW/OFException.h * * @brief The base class for all exceptions in ObjFW * * The OFException class is the base class for all exceptions in ObjFW, except * the OFAllocFailedException. */ @interface OFException: OFObject { void *_backtrace[OFBacktraceSize]; } /** * @brief Creates a new, autoreleased exception. * * @return A new, autoreleased exception */ |
︙ | ︙ | |||
172 173 174 175 176 177 178 | */ - (nullable OFArray OF_GENERIC(OFString *) *)backtrace; @end #ifdef __cplusplus extern "C" { #endif | | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | */ - (nullable OFArray OF_GENERIC(OFString *) *)backtrace; @end #ifdef __cplusplus extern "C" { #endif extern OFString *OFStrError(int errNo); #ifdef OF_WINDOWS extern OFString *OFWindowsStatusToString(LSTATUS status); #endif #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFException.m from [bf7ff24437] to [21f1fa3002].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #ifdef HAVE_DLFCN_H # include <dlfcn.h> #endif #import "OFException.h" #import "OFArray.h" #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFLockFailedException.h" #import "OFUnlockFailedException.h" | > > > < < < < | | | | > | > > > | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | #ifdef HAVE_DLFCN_H # include <dlfcn.h> #endif #import "OFException.h" #import "OFArray.h" #import "OFLocale.h" #ifdef OF_HAVE_THREADS # import "OFPlainMutex.h" #endif #import "OFString.h" #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFLockFailedException.h" #import "OFUnlockFailedException.h" #if defined(OF_WINDOWS) && defined(OF_HAVE_SOCKETS) # include <winerror.h> #endif #if defined(OF_ARM) && !defined(__ARM_DWARF_EH__) # define HAVE_ARM_EHABI_EXCEPTIONS #endif struct _Unwind_Context; typedef enum { _URC_OK = 0, _URC_END_OF_STACK = 5 } _Unwind_Reason_Code; struct BacktraceCtx { void **backtrace; uint8_t i; }; #ifdef HAVE__UNWIND_BACKTRACE extern _Unwind_Reason_Code _Unwind_Backtrace( _Unwind_Reason_Code (*)(struct _Unwind_Context *, void *), void *); #endif #ifndef HAVE_ARM_EHABI_EXCEPTIONS extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *); #else extern int _Unwind_VRS_Get(struct _Unwind_Context *, int, uint32_t, int, void *); #endif #if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS) static OFPlainMutex mutex; OF_CONSTRUCTOR() { OFEnsure(OFPlainMutexNew(&mutex) == 0); } OF_DESTRUCTOR() { OFPlainMutexFree(&mutex); } #endif OFString * OFStrError(int errNo) { OFString *ret; #ifdef HAVE_STRERROR_R char buffer[256]; #endif if (errNo == 0) |
︙ | ︙ | |||
185 186 187 188 189 190 191 | if (strerror_r(errNo, buffer, 256) != 0) return @"Unknown error (strerror_r failed)"; ret = [OFString stringWithCString: buffer encoding: [OFLocale encoding]]; #else # ifdef OF_HAVE_THREADS | | | | | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | if (strerror_r(errNo, buffer, 256) != 0) return @"Unknown error (strerror_r failed)"; ret = [OFString stringWithCString: buffer encoding: [OFLocale encoding]]; #else # ifdef OF_HAVE_THREADS if (OFPlainMutexLock(&mutex) != 0) @throw [OFLockFailedException exception]; @try { # endif ret = [OFString stringWithCString: strerror(errNo) encoding: [OFLocale encoding]]; # ifdef OF_HAVE_THREADS } @finally { if (OFPlainMutexUnlock(&mutex) != 0) @throw [OFUnlockFailedException exception]; } # endif #endif return ret; } #ifdef OF_WINDOWS OFString * OFWindowsStatusToString(LSTATUS status) { OFString *string = nil; void *buffer; if ([OFSystemInfo isWindowsNT]) { if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | |
︙ | ︙ | |||
249 250 251 252 253 254 255 | return string; } #endif #ifdef HAVE__UNWIND_BACKTRACE static _Unwind_Reason_Code | | | | | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | return string; } #endif #ifdef HAVE__UNWIND_BACKTRACE static _Unwind_Reason_Code backtraceCallback(struct _Unwind_Context *ctx, void *data) { struct BacktraceCtx *bt = data; if (bt->i < OFBacktraceSize) { # ifndef HAVE_ARM_EHABI_EXCEPTIONS bt->backtrace[bt->i++] = (void *)_Unwind_GetIP(ctx); # else uintptr_t ip; _Unwind_VRS_Get(ctx, 0, 15, 0, &ip); bt->backtrace[bt->i++] = (void *)(ip & ~1); |
︙ | ︙ | |||
278 279 280 281 282 283 284 | { return [[[self alloc] init] autorelease]; } #ifdef HAVE__UNWIND_BACKTRACE - (instancetype)init { | | | | < | 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | { return [[[self alloc] init] autorelease]; } #ifdef HAVE__UNWIND_BACKTRACE - (instancetype)init { struct BacktraceCtx ctx; self = [super init]; ctx.backtrace = _backtrace; ctx.i = 0; _Unwind_Backtrace(backtraceCallback, &ctx); return self; } #endif - (OFString *)description { return [OFString stringWithFormat: @"An exception of type %@ occurred!", self.class]; } - (OFArray OF_GENERIC(OFString *) *)backtrace { #ifdef HAVE__UNWIND_BACKTRACE OFMutableArray OF_GENERIC(OFString *) *backtrace = [OFMutableArray array]; void *pool = objc_autoreleasePoolPush(); for (uint8_t i = 0; i < OFBacktraceSize && _backtrace[i] != NULL; i++) { # ifdef HAVE_DLADDR Dl_info info; if (dladdr(_backtrace[i], &info)) { OFString *frame; if (info.dli_sname != NULL) { |
︙ | ︙ |
Modified src/exceptions/OFGetCurrentDirectoryPathFailedException.h from [df493545f4] to [8e5eb876c7].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
33 34 35 36 37 38 39 | } /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | > > | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | } /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased get current directory path failed * exception. * * @param errNo The errno of the error that occurred * @return A new, autoreleased get current directory failed exception */ + (instancetype)exceptionWithErrNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated get current directory path failed * exception. * * @param errNo The errno of the error that occurred * @return An initialized get current directory path failed exception */ - (instancetype)initWithErrNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFGetCurrentDirectoryPathFailedException.m from [8bd7e18c95] to [60672e8d84].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | #import "OFGetCurrentDirectoryPathFailedException.h" #import "OFString.h" @implementation OFGetCurrentDirectoryPathFailedException @synthesize errNo = _errNo; | < < < < < | | > > > > > | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #import "OFGetCurrentDirectoryPathFailedException.h" #import "OFString.h" @implementation OFGetCurrentDirectoryPathFailedException @synthesize errNo = _errNo; + (instancetype)exceptionWithErrNo: (int)errNo { return [[[self alloc] initWithErrNo: errNo] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithErrNo: (int)errNo { self = [super init]; _errNo = errNo; return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (OFString *)description { return [OFString stringWithFormat: @"Getting the current directory path failed: %@", OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFGetOptionFailedException.h from [2d9859c7e8] to [07bdd97238].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | @property (readonly, nonatomic) id object; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | < | > > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | @property (readonly, nonatomic) id object; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased get option failed exception. * * @param object The object for which the option could not be retrieved * @param errNo The errno of the error that occurred * @return A new, autoreleased get option failed exception */ + (instancetype)exceptionWithObject: (id)object errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated get option failed exception. * * @param object The object for which the option could not be retrieved * @param errNo The errno of the error that occurred * @return An initialized get option failed exception */ - (instancetype)initWithObject: (id)object errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFGetOptionFailedException.m from [a2104983ac] to [aeeadc602d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | @synthesize object = _object, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } | | < | < | < | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | @synthesize object = _object, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithObject: (id)object errNo: (int)errNo { return [[[self alloc] initWithObject: object errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithObject: (id)object errNo: (int)errNo { self = [super init]; _object = [object retain]; _errNo = errNo; return self; } - (void)dealloc { [_object release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Getting an option in an object of type %@ failed: %@", [_object class], OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFGetWindowsRegistryValueFailedException.h from [09e5521995] to [733c657ffd].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | * ObjFW/OFGetWindowsRegistryValueFailedException.h * * @brief An exception indicating that getting a Windows registry value failed. */ @interface OFGetWindowsRegistryValueFailedException: OFException { OFWindowsRegistryKey *_registryKey; | | | | | | | | | > > | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | * ObjFW/OFGetWindowsRegistryValueFailedException.h * * @brief An exception indicating that getting a Windows registry value failed. */ @interface OFGetWindowsRegistryValueFailedException: OFException { OFWindowsRegistryKey *_registryKey; OFString *_Nullable _valueName; DWORD _flags; LSTATUS _status; } /** * @brief The registry key on which getting the value at the key path failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; /** * @brief The name of the value which could not be retrieved. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *valueName; /** * @brief The status returned by RegGetValueEx(). */ @property (readonly, nonatomic) LSTATUS status; /** * @brief Creates a new, autoreleased get Windows registry value failed * exception. * * @param registryKey The registry key on which getting the value at the sub * key path failed * @param valueName The name of the value which could not be retrieved * @param status The status returned by RegGetValueEx() * @return A new, autoreleased get Windows registry value failed exception */ + (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (nullable OFString *)valueName status: (LSTATUS)status; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated get Windows registry value failed * exception. * * @param registryKey The registry key on which getting the value at the sub * key path failed * @param valueName The name of the value which could not be retrieved * @param status The status returned by RegGetValueEx() * @return An initialized get Windows registry value failed exception */ - (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (nullable OFString *)valueName status: (LSTATUS)status OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFGetWindowsRegistryValueFailedException.m from [1c37f45def] to [57087b05b3].
1 | /* | < < | | > | | | | | | > > > > > | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFGetWindowsRegistryValueFailedException.h" @implementation OFGetWindowsRegistryValueFailedException @synthesize registryKey = _registryKey, valueName = _valueName; @synthesize status = _status; + (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (OFString *)valueName status: (LSTATUS)status { return [[[self alloc] initWithRegistryKey: registryKey valueName: valueName status: status] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (OFString *)valueName status: (LSTATUS)status { self = [super init]; @try { _registryKey = [registryKey retain]; _valueName = [valueName copy]; _status = status; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_registryKey release]; [_valueName release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to get value named %@: %@", _valueName, OFWindowsStatusToString(_status)]; } @end |
Modified src/exceptions/OFHTTPRequestFailedException.h from [781508f774] to [59803d0bef].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
45 46 47 48 49 50 51 | @property (readonly, nonatomic) OFHTTPRequest *request; /** * @brief The response for the failed HTTP request. */ @property (readonly, nonatomic) OFHTTPResponse *response; | < < | > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | @property (readonly, nonatomic) OFHTTPRequest *request; /** * @brief The response for the failed HTTP request. */ @property (readonly, nonatomic) OFHTTPResponse *response; /** * @brief Creates a new, autoreleased HTTP request failed exception. * * @param request The HTTP request which failed * @param response The response for the failed HTTP request * @return A new, autoreleased HTTP request failed exception */ + (instancetype)exceptionWithRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated HTTP request failed exception. * * @param request The HTTP request which failed * @param response The response for the failed HTTP request * @return A new HTTP request failed exception */ - (instancetype)initWithRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFHTTPRequestFailedException.m from [ef8de3042e] to [02e986bf36].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | #import "OFString.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" @implementation OFHTTPRequestFailedException @synthesize request = _request, response = _response; | < < < < < | | > > > > > | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #import "OFString.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" @implementation OFHTTPRequestFailedException @synthesize request = _request, response = _response; + (instancetype)exceptionWithRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response { return [[[self alloc] initWithRequest: request response: response] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response { self = [super init]; _request = [request retain]; _response = [response retain]; return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_request release]; [_response release]; [super dealloc]; } - (OFString *)description { const char *method = OFHTTPRequestMethodName(_request.method); return [OFString stringWithFormat: @"An HTTP %s request with URL %@ failed with code %hd!", method, _request.URL, _response.statusCode]; } @end |
Modified src/exceptions/OFHashAlreadyCalculatedException.h from [44dc09adde] to [9fce34d334].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
32 33 34 35 36 37 38 | } /** * @brief The hash which has already been calculated. */ @property (readonly, nonatomic) id object; | < < | > > | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | } /** * @brief The hash which has already been calculated. */ @property (readonly, nonatomic) id object; /** * @brief Creates a new, autoreleased hash already calculated exception. * * @param object The hash which has already been calculated * @return A new, autoreleased hash already calculated exception */ + (instancetype)exceptionWithObject: (id)object; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated hash already calculated exception. * * @param object The hash which has already been calculated * @return An initialized hash already calculated exception */ - (instancetype)initWithObject: (id)object OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFHashAlreadyCalculatedException.m from [1c0b901a32] to [cf2d8e44b5].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Added src/exceptions/OFHashNotCalculatedException.h version [768ce1b6b5].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN /** * @class OFHashNotCalculatedException OFHashNotCalculatedException.h \ * ObjFW/OFHashNotCalculatedException.h * * @brief An exception indicating that the hash has not been calculated yet. */ @interface OFHashNotCalculatedException: OFException { id _object; } /** * @brief The hash which has not been calculated yet. */ @property (readonly, nonatomic) id object; /** * @brief Creates a new, autoreleased hash not calculated exception. * * @param object The hash which has not been calculated yet * @return A new, autoreleased hash not calculated exception */ + (instancetype)exceptionWithObject: (id)object; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated hash not calculated exception. * * @param object The hash which has not been calculated yet * @return An initialized hash not calculated exception */ - (instancetype)initWithObject: (id)object OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Added src/exceptions/OFHashNotCalculatedException.m version [3e84cb3642].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFHashNotCalculatedException.h" #import "OFString.h" @implementation OFHashNotCalculatedException @synthesize object = _object; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithObject: (id)object { return [[[self alloc] initWithObject: object] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithObject: (id)object { self = [super init]; _object = [object retain]; return self; } - (void)dealloc { [_object release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"The hash of type %@ has not been calculated yet!", [_object class]]; } @end |
Modified src/exceptions/OFInitializationFailedException.h from [272cc20780] to [20206324fd].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFInitializationFailedException.m from [9117449d9c] to [cfa23bb7fe].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFInvalidArgumentException.h from [4e3b286133] to [d5e2417590].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFInvalidArgumentException.m from [a6206d7da8] to [70957802ed].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFInvalidEncodingException.h from [e0b39579e5] to [393547809a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFInvalidEncodingException.m from [66ac68069c] to [7e85cac169].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFInvalidFormatException.h from [b2bd9775a2] to [e6f46ae68c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFInvalidFormatException.m from [c6e814685c] to [f3d13d03ab].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFInvalidJSONException.h from [08723a84ca] to [9ac94f6e36].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *string; /** * @brief The line in which parsing the JSON representation failed. */ @property (readonly, nonatomic) size_t line; | < < | > > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *string; /** * @brief The line in which parsing the JSON representation failed. */ @property (readonly, nonatomic) size_t line; /** * @brief Creates a new, autoreleased invalid JSON exception. * * @param string The string containing the invalid JSON representation * @param line The line in which the parsing error was encountered * @return A new, autoreleased invalid JSON exception */ + (instancetype)exceptionWithString: (nullable OFString *)string line: (size_t)line; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated invalid JSON exception. * * @param string The string containing the invalid JSON representation * @param line The line in which the parsing error was encountered * @return An initialized invalid JSON exception */ - (instancetype)initWithString: (nullable OFString *)string line: (size_t)line OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFInvalidJSONException.m from [e80457c265] to [973f5127bd].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | @synthesize string = _string, line = _line; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } | | < | < | < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | @synthesize string = _string, line = _line; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithString: (OFString *)string line: (size_t)line { return [[[self alloc] initWithString: string line: line] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithString: (OFString *)string line: (size_t)line { self = [super init]; @try { _string = [string copy]; _line = line; } @catch (id e) { |
︙ | ︙ |
Modified src/exceptions/OFInvalidServerReplyException.h from [4468aafe74] to [90e12ae8cf].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFInvalidServerReplyException.m from [0345e9b1e9] to [aae10c2dab].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFLinkFailedException.h from [be0b2a5425] to [099d3c2419].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
44 45 46 47 48 49 50 | @property (readonly, nonatomic) OFURL *destinationURL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | > > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | @property (readonly, nonatomic) OFURL *destinationURL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased link failed exception. * * @param sourceURL The source for the link * @param destinationURL The destination for the link * @param errNo The errno of the error that occurred * @return A new, autoreleased link failed exception */ + (instancetype)exceptionWithSourceURL: (OFURL *)sourceURL destinationURL: (OFURL *)destinationURL errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated link failed exception. * * @param sourceURL The source for the link * @param destinationURL The destination for the link * @param errNo The errno of the error that occurred * @return An initialized link failed exception */ - (instancetype)initWithSourceURL: (OFURL*)sourceURL destinationURL: (OFURL *)destinationURL errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFLinkFailedException.m from [b001d54d98] to [7710ab3fd2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
69 70 71 72 73 74 75 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to link file %@ to %@: %@", | | | 67 68 69 70 71 72 73 74 75 76 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to link file %@ to %@: %@", _sourceURL, _destinationURL, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFListenFailedException.h from [a314b9e246] to [32d4375802].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
46 47 48 49 50 51 52 | @property (readonly, nonatomic) int backlog; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | | > > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | @property (readonly, nonatomic) int backlog; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased listen failed exception. * * @param socket The socket which failed to listen * @param backlog The requested size of the back log * @param errNo The errno of the error that occurred * @return A new, autoreleased listen failed exception */ + (instancetype)exceptionWithSocket: (id)socket backlog: (int)backlog errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated listen failed exception. * * @param socket The socket which failed to listen * @param backlog The requested size of the back log * @param errNo The errno of the error that occurred * @return An initialized listen failed exception */ - (instancetype)initWithSocket: (id)socket backlog: (int)backlog errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFListenFailedException.m from [b0ecc966ad] to [45e185da77].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
62 63 64 65 66 67 68 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to listen in socket of type %@ with a back log of %d: %@", | | | 60 61 62 63 64 65 66 67 68 69 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to listen in socket of type %@ with a back log of %d: %@", [_socket class], _backlog, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFLoadPluginFailedException.h from [e486958965] to [7c45470186].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
36 37 38 39 40 41 42 | @property (readonly, nonatomic) OFString *path; /** * @brief The error why the plugin could not be loaded, as a string */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *error; | < < | > > | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | @property (readonly, nonatomic) OFString *path; /** * @brief The error why the plugin could not be loaded, as a string */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *error; /** * @brief Creates a new, autoreleased load plugin failed exception. * * @param path The path of the plugin which could not be loaded * @param error The error why the plugin could not be loaded, as a string * @return A new, autoreleased load plugin failed exception */ + (instancetype)exceptionWithPath: (OFString *)path error: (nullable OFString *)error; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated load plugin failed exception. * * @param path The path of the plugin which could not be loaded * @param error The error why the plugin could not be loaded, as a string * @return An initialized load plugin failed exception */ - (instancetype)initWithPath: (OFString *)path error: (nullable OFString *)error OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFLoadPluginFailedException.m from [0471728613] to [73caeab9c3].
1 | /* | < < | > > > > > < < < < < < < < < < < < | < > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFLoadPluginFailedException.h" #import "OFString.h" @implementation OFLoadPluginFailedException @synthesize path = _path, error = _error; + (instancetype)exceptionWithPath: (OFString *)path error: (OFString *)error { return [[[self alloc] initWithPath: path error: error] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithPath: (OFString *)path error: (OFString *)error { self = [super init]; @try { _path = [path copy]; _error = [error copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_path release]; [_error release]; [super dealloc]; |
︙ | ︙ |
Modified src/exceptions/OFLockFailedException.h from [2896ed28a8] to [e861f27ee4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | * @class OFLockFailedException \ * OFLockFailedException.h ObjFW/OFLockFailedException.h * * @brief An exception indicating that locking a lock failed. */ @interface OFLockFailedException: OFException { | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | * @class OFLockFailedException \ * OFLockFailedException.h ObjFW/OFLockFailedException.h * * @brief An exception indicating that locking a lock failed. */ @interface OFLockFailedException: OFException { id <OFLocking> _Nullable _lock; int _errNo; } /** * @brief The lock which could not be locked. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) id <OFLocking> lock; |
︙ | ︙ | |||
57 58 59 60 61 62 63 | * * @param lock The lock which could not be locked * @param errNo The errno of the error that occurred * @return An initialized lock failed exception */ - (instancetype)initWithLock: (nullable id <OFLocking>)lock errNo: (int)errNo OF_DESIGNATED_INITIALIZER; | < < | 55 56 57 58 59 60 61 62 63 64 | * * @param lock The lock which could not be locked * @param errNo The errno of the error that occurred * @return An initialized lock failed exception */ - (instancetype)initWithLock: (nullable id <OFLocking>)lock errNo: (int)errNo OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFLockFailedException.m from [194a416a76] to [77b32492ca].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | #import "OFLockFailedException.h" #import "OFString.h" @implementation OFLockFailedException @synthesize lock = _lock, errNo = _errNo; | | < | < | < < < < < < > | | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #import "OFLockFailedException.h" #import "OFString.h" @implementation OFLockFailedException @synthesize lock = _lock, errNo = _errNo; + (instancetype)exceptionWithLock: (id <OFLocking>)lock errNo: (int)errNo { return [[[self alloc] initWithLock: lock errNo: errNo] autorelease]; } - (instancetype)initWithLock: (id <OFLocking>)lock errNo: (int)errNo { self = [super init]; _lock = [lock retain]; _errNo = errNo; return self; } - (void)dealloc { [_lock release]; [super dealloc]; } - (OFString *)description { if (_lock != nil) return [OFString stringWithFormat: @"A lock of type %@ could not be locked: %s", [_lock class], strerror(_errNo)]; else return @"A lock could not be locked!"; } @end |
Modified src/exceptions/OFMalformedXMLException.h from [918b47a4d1] to [3b999908e6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFMalformedXMLException.m from [3254a4bf70] to [f5ceb7c800].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Deleted src/exceptions/OFMemoryNotPartOfObjectException.h version [ec71f02702].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/exceptions/OFMemoryNotPartOfObjectException.m version [58ab407fc3].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/exceptions/OFMoveItemFailedException.h from [3c8aaf82f5] to [c4c3e18fa9].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
44 45 46 47 48 49 50 | @property (readonly, nonatomic) OFURL *destinationURL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | > > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | @property (readonly, nonatomic) OFURL *destinationURL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased move item failed exception. * * @param sourceURL The original URL * @param destinationURL The new URL * @param errNo The errno of the error that occurred * @return A new, autoreleased move item failed exception */ + (instancetype)exceptionWithSourceURL: (OFURL *)sourceURL destinationURL: (OFURL *)destinationURL errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated move item failed exception. * * @param sourceURL The original URL * @param destinationURL The new URL * @param errNo The errno of the error that occurred * @return An initialized move item failed exception */ - (instancetype)initWithSourceURL: (OFURL *)sourceURL destinationURL: (OFURL *)destinationURL errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFMoveItemFailedException.m from [d8cf092187] to [4ea07cc8dd].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithSourceURL: (OFURL *)sourceURL destinationURL: (OFURL *)destinationURL | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithSourceURL: (OFURL *)sourceURL destinationURL: (OFURL *)destinationURL errNo: (int)errNo { return [[[self alloc] initWithSourceURL: sourceURL destinationURL: destinationURL errNo: errNo] autorelease]; } - (instancetype)init |
︙ | ︙ | |||
70 71 72 73 74 75 76 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to move item at %@ to %@: %@", | | | 68 69 70 71 72 73 74 75 76 77 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to move item at %@ to %@: %@", _sourceURL, _destinationURL, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFNotImplementedException.h from [c94de3583e] to [891dc14bbc].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
36 37 38 39 40 41 42 | * @brief The selector which is not or not fully implemented. */ @property (readonly, nonatomic) SEL selector; /** * @brief The object which does not (fully) implement the selector. */ | | < < | > > | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | * @brief The selector which is not or not fully implemented. */ @property (readonly, nonatomic) SEL selector; /** * @brief The object which does not (fully) implement the selector. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) id object; /** * @brief Creates a new, autoreleased not implemented exception. * * @param selector The selector which is not or not fully implemented * @param object The object which does not (fully) implement the selector * @return A new, autoreleased not implemented exception */ + (instancetype)exceptionWithSelector: (SEL)selector object: (nullable id)object; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated not implemented exception. * * @param selector The selector which is not or not fully implemented * @param object The object which does not (fully) implement the selector * @return An initialized not implemented exception */ - (instancetype)initWithSelector: (SEL)selector object: (nullable id)object OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFNotImplementedException.m from [febe4bbb90] to [c04e46d7c8].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | @synthesize selector = _selector, object = _object; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } | | < | < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | @synthesize selector = _selector, object = _object; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithSelector: (SEL)selector object: (id)object { return [[[self alloc] initWithSelector: selector object: object] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithSelector: (SEL)selector object: (id)object { self = [super init]; _selector = selector; _object = [object retain]; return self; |
︙ | ︙ |
Modified src/exceptions/OFNotOpenException.h from [ae04d94402] to [45f02f6f12].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | } /** * @brief The object which is not open, connected or bound. */ @property (readonly, nonatomic) id object; | < < | > > | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | } /** * @brief The object which is not open, connected or bound. */ @property (readonly, nonatomic) id object; /** * @brief Creates a new, autoreleased not open exception. * * @param object The object which is not open, connected or bound * @return A new, autoreleased not open exception */ + (instancetype)exceptionWithObject: (id)object; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated not open exception. * * @param object The object which is not open, connected or bound * @return An initialized not open exception */ - (instancetype)initWithObject: (id)object OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFNotOpenException.m from [45d81233dc] to [b0a200e662].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFObserveFailedException.h from [705baea80a] to [6c7bf7885c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
39 40 41 42 43 44 45 | @property (readonly, nonatomic) OFKernelEventObserver *observer; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | > > | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | @property (readonly, nonatomic) OFKernelEventObserver *observer; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased observe failed exception. * * @param observer The observer which failed to observe * @param errNo The errno of the error that occurred * @return A new, autoreleased observe failed exception */ + (instancetype)exceptionWithObserver: (OFKernelEventObserver *)observer errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated observe failed exception. * * @param observer The observer which failed to observe * @param errNo The errno of the error that occurred * @return An initialized observe failed exception */ - (instancetype)initWithObserver: (OFKernelEventObserver *)observer errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFObserveFailedException.m from [0373f3dc3e] to [1a09e82eb7].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
64 65 66 67 68 69 70 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"An observer of class %@ failed to observe: %@", | | | 62 63 64 65 66 67 68 69 70 71 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"An observer of class %@ failed to observe: %@", _observer.class, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFOpenItemFailedException.h from [34fbd4fcc7] to [bf32fbec46].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
51 52 53 54 55 56 57 | @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *mode; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *mode; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased open item failed exception. * * @param URL The URL of the item which could not be opened * @param mode A string with the mode in which the item should have been opened * @param errNo The errno of the error that occurred * @return A new, autoreleased open item failed exception |
︙ | ︙ | |||
77 78 79 80 81 82 83 | * @param errNo The errno of the error that occurred * @return A new, autoreleased open item failed exception */ + (instancetype)exceptionWithPath: (OFString *)path mode: (nullable OFString *)mode errNo: (int)errNo; | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | * @param errNo The errno of the error that occurred * @return A new, autoreleased open item failed exception */ + (instancetype)exceptionWithPath: (OFString *)path mode: (nullable OFString *)mode errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated open item failed exception. * * @param URL The URL of the item which could not be opened * @param mode A string with the mode in which the item should have been opened * @param errNo The errno of the error that occurred |
︙ | ︙ | |||
102 103 104 105 106 107 108 109 110 111 | * @param mode A string with the mode in which the item should have been opened * @param errNo The errno of the error that occurred * @return An initialized open item failed exception */ - (instancetype)initWithPath: (OFString *)path mode: (nullable OFString *)mode errNo: (int)errNo; @end OF_ASSUME_NONNULL_END | > > | 98 99 100 101 102 103 104 105 106 107 108 109 | * @param mode A string with the mode in which the item should have been opened * @param errNo The errno of the error that occurred * @return An initialized open item failed exception */ - (instancetype)initWithPath: (OFString *)path mode: (nullable OFString *)mode errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFOpenItemFailedException.m from [765498651a] to [2b4ec7a8b3].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #import "OFOpenItemFailedException.h" #import "OFString.h" #import "OFURL.h" @implementation OFOpenItemFailedException @synthesize URL = _URL, path = _path, mode = _mode, errNo = _errNo; | < < < < < | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #import "OFOpenItemFailedException.h" #import "OFString.h" #import "OFURL.h" @implementation OFOpenItemFailedException @synthesize URL = _URL, path = _path, mode = _mode, errNo = _errNo; + (instancetype)exceptionWithURL: (OFURL *)URL mode: (OFString *)mode errNo: (int)errNo { return [[[self alloc] initWithURL: URL mode: mode errNo: errNo] autorelease]; } + (instancetype)exceptionWithPath: (OFString *)path mode: (OFString *)mode errNo: (int)errNo { return [[[self alloc] initWithPath: path mode: mode errNo: errNo] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithURL: (OFURL *)URL mode: (OFString *)mode errNo: (int)errNo { self = [super init]; |
︙ | ︙ | |||
83 84 85 86 87 88 89 90 91 92 93 94 95 96 | } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_URL release]; [_path release]; [_mode release]; | > > > > > | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_URL release]; [_path release]; [_mode release]; |
︙ | ︙ | |||
105 106 107 108 109 110 111 | item = _URL; else if (_path != nil) item = _path; if (_mode != nil) return [OFString stringWithFormat: @"Failed to open item %@ with mode %@: %@", | | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 | item = _URL; else if (_path != nil) item = _path; if (_mode != nil) return [OFString stringWithFormat: @"Failed to open item %@ with mode %@: %@", item, _mode, OFStrError(_errNo)]; else return [OFString stringWithFormat: @"Failed to open item %@: %@", item, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFOpenWindowsRegistryKeyFailedException.h from [154d53c4c1] to [5fb8a73f7a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
80 81 82 83 84 85 86 | + (instancetype) exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey path: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights status: (LSTATUS)status; | | > > | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | + (instancetype) exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey path: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights status: (LSTATUS)status; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated open Windows registry key failed * exception. * * @param registryKey The registry key on which opening the subkey failed * @param path The path for the subkey that could not be opened * @param options The options for the subkey that could not be opened * @param securityAndAccessRights The security and access rights for the sub * key that could not be opened * @param status The status returned by RegOpenKeyEx() * @return An initialized open Windows registry key failed exception */ - (instancetype) initWithRegistryKey: (OFWindowsRegistryKey *)registryKey path: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights status: (LSTATUS)status OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFOpenWindowsRegistryKeyFailedException.m from [5a3399041c] to [52118b22c0].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
34 35 36 37 38 39 40 | return [[[self alloc] initWithRegistryKey: registryKey path: path options: options securityAndAccessRights: securityAndAccessRights status: status] autorelease]; } | | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | return [[[self alloc] initWithRegistryKey: registryKey path: path options: options securityAndAccessRights: securityAndAccessRights status: status] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype) initWithRegistryKey: (OFWindowsRegistryKey *)registryKey path: (OFString *)path options: (DWORD)options securityAndAccessRights: (REGSAM)securityAndAccessRights |
︙ | ︙ | |||
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_registryKey release]; [_path release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to open subkey at path %@: %@", | > > > > > | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_registryKey release]; [_path release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to open subkey at path %@: %@", _path, OFWindowsStatusToString(_status)]; } @end |
Modified src/exceptions/OFOutOfMemoryException.h from [f5d3bcfd5b] to [a0abc1f6de].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFOutOfMemoryException.m from [5abff47452] to [f0195e5a54].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFOutOfRangeException.h from [f0db0a5bed] to [ad1a11af88].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFOutOfRangeException.m from [54a6768506] to [42dae12fbe].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFReadFailedException.h from [10c62e7402] to [a4ca6ea7be].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFReadFailedException.m from [0000f46d4a] to [0a38835e23].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | #import "OFReadFailedException.h" #import "OFString.h" @implementation OFReadFailedException - (OFString *)description { | > | | > > > > | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #import "OFReadFailedException.h" #import "OFString.h" @implementation OFReadFailedException - (OFString *)description { if (_errNo != 0) return [OFString stringWithFormat: @"Failed to read %zu bytes from an object of type %@: %@", _requestedLength, [_object class], OFStrError(_errNo)]; else return [OFString stringWithFormat: @"Failed to read %zu bytes from an object of type %@", _requestedLength, [_object class]]; } @end |
Modified src/exceptions/OFReadOrWriteFailedException.h from [9ae34bfd6a] to [17403f4ccf].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFReadOrWriteFailedException.m from [8ec2463652] to [02ef4afd0b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
61 62 63 64 65 66 67 | [_object release]; [super dealloc]; } - (OFString *)description { | > | | | > > > > > | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | [_object release]; [super dealloc]; } - (OFString *)description { if (_errNo != 0) return [OFString stringWithFormat: @"Failed to read or write %zu bytes from / to an object of " @"type %@: %@", _requestedLength, [_object class], OFStrError(_errNo)]; else return [OFString stringWithFormat: @"Failed to read or write %zu bytes from / to an object of " @"type %@", _requestedLength, [_object class]]; } @end |
Modified src/exceptions/OFRemoveItemFailedException.h from [2f7e82f67e] to [c9bfaec2ab].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
39 40 41 42 43 44 45 | @property (readonly, nonatomic) OFURL *URL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | < | > > | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | @property (readonly, nonatomic) OFURL *URL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased remove failed exception. * * @param URL The URL of the item which could not be removed * @param errNo The errno of the error that occurred * @return A new, autoreleased remove item failed exception */ + (instancetype)exceptionWithURL: (OFURL *)URL errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated remove failed exception. * * @param URL The URL of the item which could not be removed * @param errNo The errno of the error that occurred * @return An initialized remove item failed exception */ - (instancetype)initWithURL: (OFURL *)URL errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFRemoveItemFailedException.m from [5f5d30d1f4] to [be28f37327].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | @synthesize URL = _URL, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } | | < | < | < | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | @synthesize URL = _URL, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithURL: (OFURL *)URL errNo: (int)errNo { return [[[self alloc] initWithURL: URL errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithURL: (OFURL *)URL errNo: (int)errNo { self = [super init]; @try { _URL = [URL copy]; _errNo = errNo; } @catch (id e) { |
︙ | ︙ | |||
63 64 65 66 67 68 69 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: | | | 58 59 60 61 62 63 64 65 66 67 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to remove item at URL %@: %@", _URL, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFResolveHostFailedException.h from [214de79488] to [26d03aec04].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | * OFResolveHostFailedException.h ObjFW/OFResolveHostFailedException.h * * @brief An exception indicating that resolving a host failed. */ @interface OFResolveHostFailedException: OFException { OFString *_host; | | | | | | | | > | > | | > | > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | * OFResolveHostFailedException.h ObjFW/OFResolveHostFailedException.h * * @brief An exception indicating that resolving a host failed. */ @interface OFResolveHostFailedException: OFException { OFString *_host; OFSocketAddressFamily _addressFamily; OFDNSResolverErrorCode _errorCode; } /** * @brief The host which could not be resolved. */ @property (readonly, nonatomic) OFString *host; /** * @brief The address family for which the host could not be resolved. */ @property (readonly, nonatomic) OFSocketAddressFamily addressFamily; /** * @brief The error code from the resolver. */ @property (readonly, nonatomic) OFDNSResolverErrorCode errorCode; /** * @brief Creates a new, autoreleased resolve host failed exception. * * @param host The host which could not be resolved * @param addressFamily The address family for which the host could not be * resolved * @param errorCode The error code from the resolver * @return A new, autoreleased address translation failed exception */ + (instancetype)exceptionWithHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily errorCode: (OFDNSResolverErrorCode)errorCode; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated resolve host failed exception. * * @param host The host which could not be resolved * @param addressFamily The address family for which the host could not be * resolved * @param errorCode The error code from the resolver * @return An initialized address translation failed exception */ - (instancetype)initWithHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily errorCode: (OFDNSResolverErrorCode)errorCode; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFResolveHostFailedException.m from [9ab8b6e961] to [a81a110c2f].
1 | /* | < < | | > | | | > > > > > | | | > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFResolveHostFailedException.h" #import "OFDNSQueryFailedException.h" #import "OFString.h" @implementation OFResolveHostFailedException @synthesize host = _host, addressFamily = _addressFamily; @synthesize errorCode = _errorCode; + (instancetype)exceptionWithHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily errorCode: (OFDNSResolverErrorCode)errorCode { return [[[self alloc] initWithHost: host addressFamily: addressFamily errorCode: errorCode] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithHost: (OFString *)host addressFamily: (OFSocketAddressFamily)addressFamily errorCode: (OFDNSResolverErrorCode)errorCode { self = [super init]; @try { _host = [host copy]; _addressFamily = addressFamily; _errorCode = errorCode; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_host release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"The host %@ could not be resolved: %@", _host, OFDNSResolverErrorCodeDescription(_errorCode)]; } @end |
Modified src/exceptions/OFRetrieveItemAttributesFailedException.h from [07675a3c0a] to [2269d1ffef].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
40 41 42 43 44 45 46 | @property (readonly, nonatomic) OFURL *URL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | < | > > | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | @property (readonly, nonatomic) OFURL *URL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased retrieve item attributes failed exception. * * @param URL The URL of the item whose attributes could not be retrieved * @param errNo The errno of the error that occurred * @return A new, autoreleased retrieve item attributes failed exception */ + (instancetype)exceptionWithURL: (OFURL *)URL errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated retrieve item attributes failed * exception. * * @param URL The URL of the item whose attributes could not be retrieved * @param errNo The errno of the error that occurred * @return An initialized retrieve item attributes failed exception */ - (instancetype)initWithURL: (OFURL *)URL errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFRetrieveItemAttributesFailedException.m from [cd9a66d72c] to [8b9c2b49f4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | @synthesize URL = _URL, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } | | < | < | < | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | @synthesize URL = _URL, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithURL: (OFURL *)URL errNo: (int)errNo { return [[[self alloc] initWithURL: URL errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithURL: (OFURL *)URL errNo: (int)errNo { self = [super init]; @try { _URL = [URL copy]; _errNo = errNo; } @catch (id e) { |
︙ | ︙ | |||
64 65 66 67 68 69 70 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to retrieve attributes for item %@: %@", | | | 59 60 61 62 63 64 65 66 67 68 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to retrieve attributes for item %@: %@", _URL, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFSandboxActivationFailedException.h from [4b78a21d95] to [3961f69a33].
1 | /* | < < | < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFException.h" OF_ASSUME_NONNULL_BEGIN @class OFSandbox; @interface OFSandboxActivationFailedException: OFException { OFSandbox *_sandbox; int _errNo; } @property (readonly, nonatomic) OFSandbox *sandbox; @property (readonly, nonatomic) int errNo; + (instancetype)exception OF_UNAVAILABLE; + (instancetype)exceptionWithSandbox: (OFSandbox *)sandbox errNo: (int)errNo; - (instancetype)init OF_UNAVAILABLE; - (instancetype)initWithSandbox: (OFSandbox *)sandbox errNo: (int)errNo OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFSandboxActivationFailedException.m from [5e9eec7605] to [6ace25dc28].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | @synthesize sandbox = _sandbox, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } | | < | < | | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | @synthesize sandbox = _sandbox, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithSandbox: (OFSandbox *)sandbox errNo: (int)errNo { return [[[self alloc] initWithSandbox: sandbox errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithSandbox: (OFSandbox *)sandbox errNo: (int)errNo { self = [super init]; _sandbox = [sandbox retain]; _errNo = errNo; return self; } - (void)dealloc { [_sandbox release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"The sandbox could not be applied: %@", OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFSeekFailedException.h from [9b32035ace] to [f6a3b56229].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | * OFSeekFailedException.h ObjFW/OFSeekFailedException.h * * @brief An exception indicating that seeking in a stream failed. */ @interface OFSeekFailedException: OFException { OFSeekableStream *_stream; | | | < < | | | > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | * OFSeekFailedException.h ObjFW/OFSeekFailedException.h * * @brief An exception indicating that seeking in a stream failed. */ @interface OFSeekFailedException: OFException { OFSeekableStream *_stream; OFFileOffset _offset; int _whence, _errNo; } /** * @brief The stream for which seeking failed. */ @property (readonly, nonatomic) OFSeekableStream *stream; /** * @brief The offset to which seeking failed. */ @property (readonly, nonatomic) OFFileOffset offset; /** * @brief To what the offset is relative. */ @property (readonly, nonatomic) int whence; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased seek failed exception. * * @param stream The stream for which seeking failed * @param offset The offset to which seeking failed * @param whence To what the offset is relative * @param errNo The errno of the error that occurred * @return A new, autoreleased seek failed exception */ + (instancetype)exceptionWithStream: (OFSeekableStream *)stream offset: (OFFileOffset)offset whence: (int)whence errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated seek failed exception. * * @param stream The stream for which seeking failed * @param offset The offset to which seeking failed * @param whence To what the offset is relative * @param errNo The errno of the error that occurred * @return An initialized seek failed exception */ - (instancetype)initWithStream: (OFSeekableStream *)stream offset: (OFFileOffset)offset whence: (int)whence errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFSeekFailedException.m from [223dd15b2f] to [8afbb45d54].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithStream: (OFSeekableStream *)stream | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithStream: (OFSeekableStream *)stream offset: (OFFileOffset)offset whence: (int)whence errNo: (int)errNo { return [[[self alloc] initWithStream: stream offset: offset whence: whence errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithStream: (OFSeekableStream *)stream offset: (OFFileOffset)offset whence: (int)whence errNo: (int)errNo { self = [super init]; _stream = [stream retain]; _offset = offset; |
︙ | ︙ | |||
68 69 70 71 72 73 74 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Seeking failed in stream of type %@: %@", | | | 66 67 68 69 70 71 72 73 74 75 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Seeking failed in stream of type %@: %@", _stream.class, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFSetItemAttributesFailedException.h from [f9744801d9] to [40e626240d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | * ObjFW/OFSetItemAttributesFailedException.h * * @brief An exception indicating an item's attributes could not be set. */ @interface OFSetItemAttributesFailedException: OFException { OFURL *_URL; | | | | | < < | | | | | > > | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | * ObjFW/OFSetItemAttributesFailedException.h * * @brief An exception indicating an item's attributes could not be set. */ @interface OFSetItemAttributesFailedException: OFException { OFURL *_URL; OFFileAttributes _attributes; OFFileAttributeKey _failedAttribute; int _errNo; } /** * @brief The URL of the item whose attributes could not be set. */ @property (readonly, nonatomic) OFURL *URL; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief The attributes that should have been set. */ @property (readonly, nonatomic) OFFileAttributes attributes; /** * @brief The first attribute that could not be set. */ @property (readonly, nonatomic) OFFileAttributeKey failedAttribute; /** * @brief Creates a new, autoreleased set item attributes failed exception. * * @param URL The URL of the item whose attributes could not be set * @param attributes The attributes that should have been set for the specified * item. * @param failedAttribute The first attribute that could not be set * @param errNo The errno of the error that occurred * @return A new, autoreleased set item attributes failed exception */ + (instancetype)exceptionWithURL: (OFURL *)URL attributes: (OFFileAttributes)attributes failedAttribute: (OFFileAttributeKey)failedAttribute errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated set item attributes failed exception. * * @param URL The URL of the item whose attributes could not be set * @param attributes The attributes that should have been set for the specified * item. * @param failedAttribute The first attribute that could not be set * @param errNo The errno of the error that occurred * @return An initialized set item attributes failed exception */ - (instancetype)initWithURL: (OFURL *)URL attributes: (OFFileAttributes)attributes failedAttribute: (OFFileAttributeKey)failedAttribute errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFSetItemAttributesFailedException.m from [780f6f2739] to [c7f09ee0c0].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithURL: (OFURL *)URL | | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithURL: (OFURL *)URL attributes: (OFFileAttributes)attributes failedAttribute: (OFFileAttributeKey)failedAttribute errNo: (int)errNo { return [[[self alloc] initWithURL: URL attributes: attributes failedAttribute: failedAttribute errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithURL: (OFURL *)URL attributes: (OFFileAttributes)attributes failedAttribute: (OFFileAttributeKey)failedAttribute errNo: (int)errNo { self = [super init]; @try { _URL = [URL copy]; _attributes = [attributes copy]; |
︙ | ︙ | |||
75 76 77 78 79 80 81 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to set attribute %@ for item %@: %@", | | | 73 74 75 76 77 78 79 80 81 82 | [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to set attribute %@ for item %@: %@", _failedAttribute, _URL, OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFSetOptionFailedException.h from [3ad19fbb9d] to [fd8e9dd895].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | @property (readonly, nonatomic) id object; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; | < < | < | > > | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | @property (readonly, nonatomic) id object; /** * @brief The errno of the error that occurred. */ @property (readonly, nonatomic) int errNo; /** * @brief Creates a new, autoreleased set option failed exception. * * @param object The object for which the option could not be set * @param errNo The errno of the error that occurred * @return A new, autoreleased set option failed exception */ + (instancetype)exceptionWithObject: (id)object errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated set option failed exception. * * @param object The object for which the option could not be set * @param errNo The errno of the error that occurred * @return An initialized set option failed exception */ - (instancetype)initWithObject: (id)object errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFSetOptionFailedException.m from [1fbb6fdc4f] to [8f19f7dfbc].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | @synthesize object = _object, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } | | < | < | < | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | @synthesize object = _object, errNo = _errNo; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithObject: (id)object errNo: (int)errNo { return [[[self alloc] initWithObject: object errNo: errNo] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithObject: (id)object errNo: (int)errNo { self = [super init]; _object = [object retain]; _errNo = errNo; return self; } - (void)dealloc { [_object release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Setting an option in an object of type %@ failed: %@", [_object class], OFStrError(_errNo)]; } @end |
Modified src/exceptions/OFSetWindowsRegistryValueFailedException.h from [d07cbbec63] to [881eab26fa].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | * ObjFW/OFSetWindowsRegistryValueFailedException.h * * @brief An exception indicating that setting a Windows registry value failed. */ @interface OFSetWindowsRegistryValueFailedException: OFException { OFWindowsRegistryKey *_registryKey; | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | * ObjFW/OFSetWindowsRegistryValueFailedException.h * * @brief An exception indicating that setting a Windows registry value failed. */ @interface OFSetWindowsRegistryValueFailedException: OFException { OFWindowsRegistryKey *_registryKey; OFString *_Nullable _valueName; OFData *_Nullable _data; DWORD _type; LSTATUS _status; } /** * @brief The registry key on which setting the value failed. */ @property (readonly, nonatomic) OFWindowsRegistryKey *registryKey; /** * @brief The name of the value which could not be set. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *valueName; /** * @brief The data to which the value could not be set. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFData *data; /** |
︙ | ︙ | |||
64 65 66 67 68 69 70 | @property (readonly, nonatomic) LSTATUS status; /** * @brief Creates a new, autoreleased set Windows registry value failed * exception. * * @param registryKey The registry key on which setting the value failed | | | | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | @property (readonly, nonatomic) LSTATUS status; /** * @brief Creates a new, autoreleased set Windows registry value failed * exception. * * @param registryKey The registry key on which setting the value failed * @param valueName The name of the value which could not be set * @param data The data to which the value could not be set * @param type The type for the value that could not be set * @param status The status returned by RegSetValueEx() * @return A new, autoreleased set Windows registry value failed exception */ + (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (nullable OFString *)valueName data: (nullable OFData *)data type: (DWORD)type status: (LSTATUS)status; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated set Windows registry value failed * exception. * * @param registryKey The registry key on which setting the value failed * @param valueName The name of the value which could not be set * @param data The data to which the value could not be set * @param type The type for the value that could not be set * @param status The status returned by RegSetValueEx() * @return An initialized set Windows registry value failed exception */ - (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (nullable OFString *)valueName data: (nullable OFData *)data type: (DWORD)type status: (LSTATUS)status OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFSetWindowsRegistryValueFailedException.m from [07e1fe5617] to [e6d28eef78].
1 | /* | < < | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFSetWindowsRegistryValueFailedException.h" #import "OFData.h" @implementation OFSetWindowsRegistryValueFailedException @synthesize registryKey = _registryKey, valueName = _valueName, data = _data; @synthesize type = _type, status = _status; + (instancetype)exceptionWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (OFString *)valueName data: (OFData *)data type: (DWORD)type status: (LSTATUS)status { return [[[self alloc] initWithRegistryKey: registryKey valueName: valueName data: data type: type status: status] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithRegistryKey: (OFWindowsRegistryKey *)registryKey valueName: (OFString *)valueName data: (OFData *)data type: (DWORD)type status: (LSTATUS)status { self = [super init]; @try { _registryKey = [registryKey retain]; _valueName = [valueName copy]; _data = [data copy]; _type = type; _status = status; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_registryKey release]; [_valueName release]; [_data release]; [super dealloc]; } - (OFString *)description { return [OFString stringWithFormat: @"Failed to set value named %@ of type %u: %@", _valueName, _type, OFWindowsStatusToString(_status)]; } @end |
Modified src/exceptions/OFStillLockedException.h from [129c6beace] to [9e844f7b24].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | * @class OFStillLockedException \ * OFStillLockedException.h ObjFW/OFStillLockedException.h * * @brief An exception indicating that a lock is still locked. */ @interface OFStillLockedException: OFException { | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | * @class OFStillLockedException \ * OFStillLockedException.h ObjFW/OFStillLockedException.h * * @brief An exception indicating that a lock is still locked. */ @interface OFStillLockedException: OFException { id <OFLocking> _Nullable _lock; } /** * @brief The lock which is still locked. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) id <OFLocking> lock; |
︙ | ︙ |
Modified src/exceptions/OFStillLockedException.m from [befdc7b2dc] to [3bdcf688e2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Added src/exceptions/OFTLSHandshakeFailedException.h version [624dc0f97d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFException.h" #ifndef OF_HAVE_SOCKETS # error No sockets available! #endif #import "OFTLSStream.h" OF_ASSUME_NONNULL_BEGIN #ifdef __cplusplus extern "C" { #endif extern int _OFTLSHandshakeFailedException_reference; #ifdef __cplusplus } #endif /** * @class OFTLSHandshakeFailedException \ * OFTLSHandshakeFailedException.h ObjFW/OFTLSHandshakeFailedException.h * * @brief An exception indicating that a TLS handshake. */ @interface OFTLSHandshakeFailedException: OFException { OFTLSStream *_stream; OFString *_Nullable _host; OFTLSStreamErrorCode _errorCode; } /** * @brief The TLS stream which failed the handshake. */ @property (readonly, nonatomic) OFTLSStream *stream; /** * @brief The host for the handshake. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *host; /** * @brief The error code from the TLS stream. */ @property (readonly, nonatomic) OFTLSStreamErrorCode errorCode; /** * @brief Creates a new, autoreleased TLS handshake failed exception. * * @param stream The TLS stream which failed the handshake * @param host The host for the handshake * @param errorCode The error code from the TLS stream * @return A new, autoreleased TLS handshake failed exception */ + (instancetype)exceptionWithStream: (OFTLSStream *)stream host: (nullable OFString *)host errorCode: (OFTLSStreamErrorCode)errorCode; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated TLS handshake failed exception. * * @param stream The TLS stream which failed the handshake * @param host The host for the handshake * @param errorCode The error code from the TLS stream * @return An initialized TLS handshake failed exception */ - (instancetype)initWithStream: (OFTLSStream *)stream host: (nullable OFString *)host errorCode: (OFTLSStreamErrorCode)errorCode OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Added src/exceptions/OFTLSHandshakeFailedException.m version [9f825e73f8].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFTLSHandshakeFailedException.h" #import "OFString.h" int _OFTLSHandshakeFailedException_reference; @implementation OFTLSHandshakeFailedException @synthesize stream = _stream, host = _host, errorCode = _errorCode; + (instancetype)exceptionWithStream: (OFTLSStream *)stream host: (OFString *)host errorCode: (OFTLSStreamErrorCode)errorCode { return [[[self alloc] initWithStream: stream host: host errorCode: errorCode] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithStream: (OFTLSStream *)stream host: (OFString *)host errorCode: (OFTLSStreamErrorCode)errorCode { self = [super init]; @try { _stream = [stream retain]; _host = [host copy]; _errorCode = errorCode; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_stream release]; [_host release]; [super dealloc]; } - (OFString *)description { if (_host != nil) return [OFString stringWithFormat: @"TLS handshake in class %@ with host %@ failed: %@", _stream.class, _host, OFTLSStreamErrorCodeDescription(_errorCode)]; else return [OFString stringWithFormat: @"TLS handshake in class %@ failed: %@", _stream.class, OFTLSStreamErrorCodeDescription(_errorCode)]; } @end |
Modified src/exceptions/OFThreadJoinFailedException.h from [b527bd48d4] to [8bf49777b7].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | * @class OFThreadJoinFailedException \ * OFThreadJoinFailedException.h ObjFW/OFThreadJoinFailedException.h * * @brief An exception indicating that joining a thread failed. */ @interface OFThreadJoinFailedException: OFException { | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | * @class OFThreadJoinFailedException \ * OFThreadJoinFailedException.h ObjFW/OFThreadJoinFailedException.h * * @brief An exception indicating that joining a thread failed. */ @interface OFThreadJoinFailedException: OFException { OFThread *_Nullable _thread; int _errNo; } /** * @brief The thread which could not be joined. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFThread *thread; |
︙ | ︙ | |||
52 53 54 55 56 57 58 59 60 61 62 63 64 65 | * * @param thread The thread which could not be joined * @param errNo The errno of the error that occurred * @return A new, autoreleased thread join failed exception */ + (instancetype)exceptionWithThread: (nullable OFThread *)thread errNo: (int)errNo; /** * @brief Initializes an already allocated thread join failed exception. * * @param thread The thread which could not be joined * @param errNo The errno of the error that occurred * @return An initialized thread join failed exception | > > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | * * @param thread The thread which could not be joined * @param errNo The errno of the error that occurred * @return A new, autoreleased thread join failed exception */ + (instancetype)exceptionWithThread: (nullable OFThread *)thread errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated thread join failed exception. * * @param thread The thread which could not be joined * @param errNo The errno of the error that occurred * @return An initialized thread join failed exception |
︙ | ︙ |
Modified src/exceptions/OFThreadJoinFailedException.m from [a63740fb47] to [3ceaee16ab].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | #import "OFThreadJoinFailedException.h" #import "OFString.h" #import "OFThread.h" @implementation OFThreadJoinFailedException @synthesize thread = _thread, errNo = _errNo; | | < | > | > > > | < | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #import "OFThreadJoinFailedException.h" #import "OFString.h" #import "OFThread.h" @implementation OFThreadJoinFailedException @synthesize thread = _thread, errNo = _errNo; + (instancetype)exceptionWithThread: (OFThread *)thread errNo: (int)errNo { return [[[self alloc] initWithThread: thread errNo: errNo] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithThread: (OFThread *)thread errNo: (int)errNo { self = [super init]; _thread = [thread retain]; _errNo = errNo; return self; |
︙ | ︙ |
Modified src/exceptions/OFThreadStartFailedException.h from [3e69c81f5f] to [d864107627].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | * @class OFThreadStartFailedException \ * OFThreadStartFailedException.h ObjFW/OFThreadStartFailedException.h * * @brief An exception indicating that starting a thread failed. */ @interface OFThreadStartFailedException: OFException { | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | * @class OFThreadStartFailedException \ * OFThreadStartFailedException.h ObjFW/OFThreadStartFailedException.h * * @brief An exception indicating that starting a thread failed. */ @interface OFThreadStartFailedException: OFException { OFThread *_Nullable _thread; int _errNo; } /** * @brief The thread which could not be started. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFThread *thread; |
︙ | ︙ | |||
52 53 54 55 56 57 58 59 60 61 62 63 64 65 | * * @param thread The thread which could not be started * @param errNo The errno of the error that occurred * @return A new, autoreleased thread start failed exception */ + (instancetype)exceptionWithThread: (nullable OFThread *)thread errNo: (int)errNo; /** * @brief Initializes an already allocated thread start failed exception. * * @param thread The thread which could not be started * @param errNo The errno of the error that occurred * @return An initialized thread start failed exception | > > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | * * @param thread The thread which could not be started * @param errNo The errno of the error that occurred * @return A new, autoreleased thread start failed exception */ + (instancetype)exceptionWithThread: (nullable OFThread *)thread errNo: (int)errNo; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated thread start failed exception. * * @param thread The thread which could not be started * @param errNo The errno of the error that occurred * @return An initialized thread start failed exception |
︙ | ︙ |
Modified src/exceptions/OFThreadStartFailedException.m from [1c0a578d89] to [4df0dddce1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | #import "OFThreadStartFailedException.h" #import "OFString.h" #import "OFThread.h" @implementation OFThreadStartFailedException @synthesize thread = _thread, errNo = _errNo; | | < | > | > > > | < | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #import "OFThreadStartFailedException.h" #import "OFString.h" #import "OFThread.h" @implementation OFThreadStartFailedException @synthesize thread = _thread, errNo = _errNo; + (instancetype)exceptionWithThread: (OFThread *)thread errNo: (int)errNo { return [[[self alloc] initWithThread: thread errNo: errNo] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithThread: (OFThread *)thread errNo: (int)errNo { self = [super init]; _thread = [thread retain]; _errNo = errNo; return self; |
︙ | ︙ |
Modified src/exceptions/OFThreadStillRunningException.h from [bb48ef30be] to [2982187d56].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | * @class OFThreadStillRunningException \ * OFThreadStillRunningException.h ObjFW/OFThreadStillRunningException.h * * @brief An exception indicating that a thread is still running. */ @interface OFThreadStillRunningException: OFException { | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | * @class OFThreadStillRunningException \ * OFThreadStillRunningException.h ObjFW/OFThreadStillRunningException.h * * @brief An exception indicating that a thread is still running. */ @interface OFThreadStillRunningException: OFException { OFThread *_Nullable _thread; } /** * @brief The thread which is still running. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFThread *thread; |
︙ | ︙ |
Modified src/exceptions/OFThreadStillRunningException.m from [408dabc9f4] to [08b6a2fa91].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFTruncatedDataException.h from [d9329704f6] to [8a558e22e7].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFTruncatedDataException.m from [3c7848233b] to [d3465afc55].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFUnboundNamespaceException.h from [8c7398ae7e] to [cc4424a80d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
35 36 37 38 39 40 41 | /** * @brief The unbound namespace. */ #ifndef __cplusplus @property (readonly, nonatomic) OFString *namespace; #else | | < < | | | | | > > | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | /** * @brief The unbound namespace. */ #ifndef __cplusplus @property (readonly, nonatomic) OFString *namespace; #else @property (readonly, nonatomic, getter=namespace) OFString *nameSpace; #endif /** * @brief The element in which the namespace was not bound. */ @property (readonly, nonatomic) OFXMLElement *element; /** * @brief Creates a new, autoreleased unbound namespace exception. * * @param nameSpace The namespace which is unbound * @param element The element in which the namespace was not bound * @return A new, autoreleased unbound namespace exception */ + (instancetype)exceptionWithNamespace: (OFString *)nameSpace element: (OFXMLElement *)element; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated unbound namespace exception. * * @param nameSpace The namespace which is unbound * @param element The element in which the namespace was not bound * @return An initialized unbound namespace exception */ - (instancetype)initWithNamespace: (OFString *)nameSpace element: (OFXMLElement *)element OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFUnboundNamespaceException.m from [0746a32c6a] to [8d26c2cfa6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFUnboundPrefixException.h from [e2787d1963] to [6d7bca5c41].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
39 40 41 42 43 44 45 | @property (readonly, nonatomic) OFString *prefix; /** * @brief The parser which encountered the unbound prefix. */ @property (readonly, nonatomic) OFXMLParser *parser; | < < | > > | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | @property (readonly, nonatomic) OFString *prefix; /** * @brief The parser which encountered the unbound prefix. */ @property (readonly, nonatomic) OFXMLParser *parser; /** * @brief Creates a new, autoreleased unbound prefix exception. * * @param prefix The prefix which is unbound * @param parser The parser which encountered the unbound prefix * @return A new, autoreleased unbound prefix exception */ + (instancetype)exceptionWithPrefix: (OFString *)prefix parser: (OFXMLParser *)parser; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated unbound prefix exception. * * @param prefix The prefix which is unbound * @param parser The parser which encountered the unbound prefix * @return An initialized unbound prefix exception */ - (instancetype)initWithPrefix: (OFString *)prefix parser: (OFXMLParser *)parser OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFUnboundPrefixException.m from [0c71a73c4b] to [09d3302162].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | } - (instancetype)init { OF_INVALID_INIT_METHOD } | | < | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithPrefix: (OFString *)prefix parser: (OFXMLParser *)parser { self = [super init]; @try { _prefix = [prefix copy]; _parser = [parser retain]; } @catch (id e) { |
︙ | ︙ |
Modified src/exceptions/OFUndefinedKeyException.h from [3f22266364] to [1d0c472b52].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | * * @brief An exception indicating that a key is undefined (e.g. for Key Value * Coding). */ @interface OFUndefinedKeyException: OFException { id _object; | | | < < | < | | | < | > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | * * @brief An exception indicating that a key is undefined (e.g. for Key Value * Coding). */ @interface OFUndefinedKeyException: OFException { id _object; OFString *_Nullable _key; id _Nullable _value; } /** * @brief The object on which the key is undefined. */ @property (readonly, nonatomic) id object; /** * @brief The key which is undefined. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFString *key; /** * @brief The value for the undefined key */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) id value; /** * @brief Creates a new, autoreleased undefined key exception. * * @param object The object on which the key is undefined * @param key The key which is undefined * * @return A new, autoreleased undefined key exception */ + (instancetype)exceptionWithObject: (id)object key: (OFString *)key; /** * @brief Creates a new, autoreleased undefined key exception. * * @param object The object on which the key is undefined * @param key The key which is undefined * @param value The value for the undefined key * * @return A new, autoreleased undefined key exception */ + (instancetype)exceptionWithObject: (id)object key: (nullable OFString *)key value: (nullable id)value; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated undefined key exception. * * @param object The object on which the key is undefined * @param key The key which is undefined * * @return An initialized undefined key exception */ - (instancetype)initWithObject: (id)object key: (OFString *)key; /** * @brief Initializes an already allocated undefined key exception. * * @param object The object on which the key is undefined * @param key The key which is undefined * @param value The value for the undefined key * * @return An initialized undefined key exception */ - (instancetype)initWithObject: (id)object key: (nullable OFString *)key value: (nullable id)value OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFUndefinedKeyException.m from [150023b635] to [fa0cc877cd].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | @synthesize object = _object, key = _key, value = _value; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } | | < | < | < | < < | < < | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | @synthesize object = _object, key = _key, value = _value; + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } + (instancetype)exceptionWithObject: (id)object key: (OFString *)key { return [[[self alloc] initWithObject: object key: key] autorelease]; } + (instancetype)exceptionWithObject: (id)object key: (OFString *)key value: (id)value { return [[[self alloc] initWithObject: object key: key value: value] autorelease]; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (instancetype)initWithObject: (id)object key: (OFString *)key { return [self initWithObject: object key: key value: nil]; } - (instancetype)initWithObject: (id)object key: (OFString *)key value: (id)value { self = [super init]; @try { _object = [object retain]; _key = [key copy]; _value = [value retain]; |
︙ | ︙ |
Modified src/exceptions/OFUnknownXMLEntityException.h from [cbe0c1933d] to [fdd37fe4f2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
40 41 42 43 44 45 46 | * @brief Creates a new, autoreleased unknown XML entity exception. * * @param entityName The name of the unknown XML entity * @return A new, autoreleased unknown XML entity exception */ + (instancetype)exceptionWithEntityName: (OFString *)entityName; | | > > | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | * @brief Creates a new, autoreleased unknown XML entity exception. * * @param entityName The name of the unknown XML entity * @return A new, autoreleased unknown XML entity exception */ + (instancetype)exceptionWithEntityName: (OFString *)entityName; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated unknown XML entity exception. * * @param entityName The name of the unknown XML entity * @return An initialized unknown XML entity exception */ - (instancetype)initWithEntityName: (OFString *)entityName OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFUnknownXMLEntityException.m from [0ddad3269c] to [87056195a2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | @synthesize entityName = _entityName; + (instancetype)exceptionWithEntityName: (OFString *)entityName { return [[[self alloc] initWithEntityName: entityName] autorelease]; } | | | > > > > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | @synthesize entityName = _entityName; + (instancetype)exceptionWithEntityName: (OFString *)entityName { return [[[self alloc] initWithEntityName: entityName] autorelease]; } + (instancetype)exception { OF_UNRECOGNIZED_SELECTOR } - (instancetype)initWithEntityName: (OFString *)entityName { self = [super init]; @try { _entityName = [entityName copy]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)init { OF_INVALID_INIT_METHOD } - (void)dealloc { [_entityName release]; [super dealloc]; } |
︙ | ︙ |
Modified src/exceptions/OFUnlockFailedException.h from [23e77d50e9] to [ab29b208b2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | * @class OFUnlockFailedException \ * OFUnlockFailedException.h ObjFW/OFUnlockFailedException.h * * @brief An exception indicating that unlocking a lock failed. */ @interface OFUnlockFailedException: OFException { | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | * @class OFUnlockFailedException \ * OFUnlockFailedException.h ObjFW/OFUnlockFailedException.h * * @brief An exception indicating that unlocking a lock failed. */ @interface OFUnlockFailedException: OFException { id <OFLocking> _Nullable _lock; int _errNo; } /** * @brief The lock which could not be unlocked. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) id <OFLocking> lock; |
︙ | ︙ | |||
57 58 59 60 61 62 63 | * * @param lock The lock which could not be unlocked * @param errNo The errno of the error that occurred * @return An initialized unlock failed exception */ - (instancetype)initWithLock: (nullable id <OFLocking>)lock errNo: (int)errNo OF_DESIGNATED_INITIALIZER; | < < | 55 56 57 58 59 60 61 62 63 64 | * * @param lock The lock which could not be unlocked * @param errNo The errno of the error that occurred * @return An initialized unlock failed exception */ - (instancetype)initWithLock: (nullable id <OFLocking>)lock errNo: (int)errNo OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFUnlockFailedException.m from [f8ba9a8de1] to [68e65cd613].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | #import "OFUnlockFailedException.h" #import "OFString.h" @implementation OFUnlockFailedException @synthesize lock = _lock, errNo = _errNo; | | < | < | < < < < < < > | | | > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #import "OFUnlockFailedException.h" #import "OFString.h" @implementation OFUnlockFailedException @synthesize lock = _lock, errNo = _errNo; + (instancetype)exceptionWithLock: (id <OFLocking>)lock errNo: (int)errNo { return [[[self alloc] initWithLock: lock errNo: errNo] autorelease]; } - (instancetype)initWithLock: (id <OFLocking>)lock errNo: (int)errNo { self = [super init]; _lock = [lock retain]; _errNo = errNo; return self; } - (void)dealloc { [_lock release]; [super dealloc]; } - (OFString *)description { if (_lock != nil) return [OFString stringWithFormat: @"A lock of type %@ could not be unlocked: %s", [_lock class], strerror(_errNo)]; else return @"A lock could not be unlocked!"; } @end |
Modified src/exceptions/OFUnsupportedProtocolException.h from [0d4f7d0a94] to [8223e3796e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | * ObjFW/OFUnsupportedProtocolException.h * * @brief An exception indicating that the protocol specified by the URL is not * supported. */ @interface OFUnsupportedProtocolException: OFException { | | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | * ObjFW/OFUnsupportedProtocolException.h * * @brief An exception indicating that the protocol specified by the URL is not * supported. */ @interface OFUnsupportedProtocolException: OFException { OFURL *_Nullable _URL; } /** * @brief The URL whose protocol is unsupported. */ @property OF_NULLABLE_PROPERTY (readonly, nonatomic) OFURL *URL; /** * @brief Creates a new, autoreleased unsupported protocol exception. * * @param URL The URL whose protocol is unsupported * @return A new, autoreleased unsupported protocol exception */ + (instancetype)exceptionWithURL: (nullable OFURL*)URL; /** * @brief Initializes an already allocated unsupported protocol exception * * @param URL The URL whose protocol is unsupported * @return An initialized unsupported protocol exception */ - (instancetype)initWithURL: (nullable OFURL*)URL OF_DESIGNATED_INITIALIZER; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFUnsupportedProtocolException.m from [a55564c11d] to [ba097adb5e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFUnsupportedVersionException.h from [f8d8b879c7] to [fd604be220].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
32 33 34 35 36 37 38 | } /** * @brief The version which is unsupported. */ @property (readonly, nonatomic) OFString *version; | < < | > > | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | } /** * @brief The version which is unsupported. */ @property (readonly, nonatomic) OFString *version; /** * @brief Creates a new, autoreleased unsupported version exception. * * @param version The version which is unsupported * @return A new, autoreleased unsupported version exception */ + (instancetype)exceptionWithVersion: (OFString *)version; + (instancetype)exception OF_UNAVAILABLE; /** * @brief Initializes an already allocated unsupported protocol exception. * * @param version The version which is unsupported * @return An initialized unsupported version exception */ - (instancetype)initWithVersion: (OFString *)version OF_DESIGNATED_INITIALIZER; - (instancetype)init OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFUnsupportedVersionException.m from [3987a818e5] to [ae8969b353].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/exceptions/OFWriteFailedException.h from [052da38254] to [52a0c0096f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
34 35 36 37 38 39 40 | * @brief The number of bytes already written before the write failed. * * This can be used to make sure that a retry does not write data already * written before. */ @property (readonly, nonatomic) size_t bytesWritten; | < < < < | | | > > > > | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | * @brief The number of bytes already written before the write failed. * * This can be used to make sure that a retry does not write data already * written before. */ @property (readonly, nonatomic) size_t bytesWritten; /** * @brief Creates a new, autoreleased write failed exception. * * @param object The object from which reading or to which writing failed * @param requestedLength The requested length of the data that could not be * read / written * @param bytesWritten The amount of bytes already written before the write * failed * @param errNo The errno of the error that occurred * @return A new, autoreleased write failed exception */ + (instancetype)exceptionWithObject: (id)object requestedLength: (size_t)requestedLength bytesWritten: (size_t)bytesWritten errNo: (int)errNo; + (instancetype)exceptionWithObject: (id)object requestedLength: (size_t)requestedLength errNo: (int)errNo OF_UNAVAILABLE; /** * @brief Initializes an already allocated write failed exception. * * @param object The object from which reading or to which writing failed * @param requestedLength The requested length of the data that could not be * read / written * @param bytesWritten The amount of bytes already written before the write * failed * @param errNo The errno of the error that occurred * @return A new open file failed exception */ - (instancetype)initWithObject: (id)object requestedLength: (size_t)requestedLength bytesWritten: (size_t)bytesWritten errNo: (int)errNo OF_DESIGNATED_INITIALIZER; - (instancetype)initWithObject: (id)object requestedLength: (size_t)requestedLength errNo: (int)errNo OF_UNAVAILABLE; @end OF_ASSUME_NONNULL_END |
Modified src/exceptions/OFWriteFailedException.m from [5aba14e7b3] to [1eca55cb4e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
62 63 64 65 66 67 68 | _bytesWritten = bytesWritten; return self; } - (OFString *)description { | > | | | | | > > > > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | _bytesWritten = bytesWritten; return self; } - (OFString *)description { if (_errNo != 0) return [OFString stringWithFormat: @"Failed to write %zu bytes (after %zu bytes written) to " @"an object of type %@: %@", _requestedLength, _bytesWritten, [_object class], OFStrError(_errNo)]; else return [OFString stringWithFormat: @"Failed to write %zu bytes (after %zu bytes written) to " @"an object of type %@", _requestedLength, _bytesWritten, [_object class]]; } @end |
Modified src/forwarding/apple-forwarding-arm.S from [bb35b86b46] to [638359a9cd].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" .globl _OFForward .globl _OFForward_stret .section __TEXT, __objc_methname, cstring_literals str_forwardingTargetForSelector_: .asciz "forwardingTargetForSelector:" .section __DATA, __objc_selrefs, literal_pointers, no_dead_strip sel_forwardingTargetForSelector_: .long str_forwardingTargetForSelector_ .section __DATA, __objc_imageinfo, regular, no_dead_strip .long 0, 0 .section __TEXT, __text, regular, pure_instructions .arm .align 2 _OFForward: stmfd sp!, {r0-r4, lr} vstmdb sp!, {d0-d7} ldr r4, sel_forwardingTargetForSelector_$indirect_L0 L0: ldr r4, [pc, r4] |
︙ | ︙ | |||
66 67 68 69 70 71 72 | ldmfd sp!, {r1-r4, lr} b _objc_msgSend 0: vldmia sp!, {d0-d7} ldmfd sp!, {r0-r4, lr} | | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | ldmfd sp!, {r1-r4, lr} b _objc_msgSend 0: vldmia sp!, {d0-d7} ldmfd sp!, {r0-r4, lr} b _OFMethodNotFound .data_region sel_forwardingTargetForSelector_$indirect_L0: .long sel_forwardingTargetForSelector_-(L0+8) .end_data_region .align 2 _OFForward_stret: stmfd sp!, {r0-r4, lr} vstmdb sp!, {d0-d7} ldr r4, sel_forwardingTargetForSelector_$indirect_L1 L1: ldr r4, [pc, r4] |
︙ | ︙ | |||
114 115 116 117 118 119 120 | ldmfd sp!, {r2-r4, lr} b _objc_msgSend_stret 0: vldmia sp!, {d0-d7} ldmfd sp!, {r0-r4, lr} | | | 112 113 114 115 116 117 118 119 120 121 122 123 124 | ldmfd sp!, {r2-r4, lr} b _objc_msgSend_stret 0: vldmia sp!, {d0-d7} ldmfd sp!, {r0-r4, lr} b _OFMethodNotFound_stret .data_region sel_forwardingTargetForSelector_$indirect_L1: .long sel_forwardingTargetForSelector_-(L1+8) .end_data_region |
Modified src/forwarding/apple-forwarding-arm64.S from [b601a8acbc] to [d2adf305f5].
1 | /* | < < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" .globl _OFForward .globl _OFForward_stret .section __TEXT, __objc_methname, cstring_literals str_forwardingTargetForSelector_: .asciz "forwardingTargetForSelector:" .section __DATA, __objc_selrefs, literal_pointers, no_dead_strip sel_forwardingTargetForSelector_: .quad str_forwardingTargetForSelector_ .section __DATA, __objc_imageinfo, regular, no_dead_strip .long 0, 0 .section __TEXT, __text, regular, pure_instructions .align 2 _OFForward: _OFForward_stret: stp fp, lr, [sp, #-208]! mov fp, sp sub sp, sp, #208 /* Save all arguments, x8 and x19 */ stp x0, x1, [sp] stp x2, x3, [sp, #16] |
︙ | ︙ | |||
93 94 95 96 97 98 99 | 0: ldp x0, x1, [sp] ldr x19, [sp, #72] mov sp, fp ldp fp, lr, [sp], #208 | | | 91 92 93 94 95 96 97 98 | 0: ldp x0, x1, [sp] ldr x19, [sp, #72] mov sp, fp ldp fp, lr, [sp], #208 b _OFMethodNotFound |
Modified src/forwarding/apple-forwarding-i386.S from [288bef5c12] to [11f716a457].
1 | /* | < < | < < | | | | | | | | | | | | | < | < | | | | < | | | | < | | | | | | | | | | | | | | | | | | < | < | | | | < | > > > > < < < < < | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" .globl _OFForward .globl _OFForward_stret .section __TEXT, __cstring, cstring_literals str_forwardingTargetForSelector_: .asciz "forwardingTargetForSelector:" .section __OBJC, __message_refs, literal_pointers, no_dead_strip sel_forwardingTargetForSelector_: .long str_forwardingTargetForSelector_ .section __OBJC, __image_info .long 0, 0 .section __TEXT, __text, regular, pure_instructions _OFForward: pushl %ebp movl %esp, %ebp pushl %ebx subl $20, %esp call get_eip 0: movl 8(%ebp), %eax movl %eax, (%esp) call _object_getClass movl %eax, (%esp) movl sel_forwardingTargetForSelector_-0b(%ebx), %eax movl %eax, 4(%esp) call _class_respondsToSelector testl %eax, %eax jz 0f movl 8(%ebp), %eax movl %eax, (%esp) movl sel_forwardingTargetForSelector_-0b(%ebx), %eax movl %eax, 4(%esp) movl 12(%ebp), %eax movl %eax, 8(%esp) call _objc_msgSend testl %eax, %eax jz 0f cmpl 8(%ebp), %eax je 0f movl %eax, 8(%ebp) addl $20, %esp popl %ebx popl %ebp jmp _objc_msgSend 0: addl $20, %esp popl %ebx popl %ebp jmp _OFMethodNotFound _OFForward_stret: pushl %ebp movl %esp, %ebp pushl %ebx subl $20, %esp call get_eip 0: movl 12(%ebp), %eax movl %eax, (%esp) call _object_getClass movl %eax, (%esp) movl sel_forwardingTargetForSelector_-0b(%ebx), %eax movl %eax, 4(%esp) call _class_respondsToSelector testl %eax, %eax jz 0f movl 12(%ebp), %eax movl %eax, (%esp) movl sel_forwardingTargetForSelector_-0b(%ebx), %eax movl %eax, 4(%esp) movl 16(%ebp), %eax movl %eax, 8(%esp) call _objc_msgSend testl %eax, %eax jz 0f cmpl 12(%ebp), %eax je 0f movl %eax, 12(%ebp) addl $20, %esp popl %ebx popl %ebp jmp _objc_msgSend_stret 0: addl $20, %esp popl %ebx popl %ebp jmp _OFMethodNotFound_stret get_eip: movl (%esp), %ebx ret |
Modified src/forwarding/apple-forwarding-powerpc.S from [f6d7016a9d] to [8f7b914664].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" .globl _OFForward .globl _OFForward_stret .section __TEXT, __cstring, cstring_literals str_forwardingTargetForSelector_: .asciz "forwardingTargetForSelector:" .section __OBJC, __message_refs sel_forwardingTargetForSelector_: .long str_forwardingTargetForSelector_ .section __OBJC, __image_info .long 0, 0 .section __TEXT, __text, regular, pure_instructions _OFForward: mflr r0 stw r0, 8(r1) stwu r1, -192(r1) /* * Save all arguments and r13. * |
︙ | ︙ | |||
128 129 130 131 132 133 134 | lwz r3, 216(r1) lwz r4, 220(r1) addi r1, r1, 192 lwz r0, 8(r1) mtlr r0 | | | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | lwz r3, 216(r1) lwz r4, 220(r1) addi r1, r1, 192 lwz r0, 8(r1) mtlr r0 b _OFMethodNotFound _OFForward_stret: mflr r0 stw r0, 8(r1) stwu r1, -184(r1) /* * Save all arguments and r13. * |
︙ | ︙ | |||
234 235 236 237 238 239 240 | lwz r4, 212(r1) lwz r5, 216(r1) addi r1, r1, 184 lwz r0, 8(r1) mtlr r0 | | | 232 233 234 235 236 237 238 239 | lwz r4, 212(r1) lwz r5, 216(r1) addi r1, r1, 184 lwz r0, 8(r1) mtlr r0 b _OFMethodNotFound_stret |
Modified src/forwarding/apple-forwarding-x86_64.S from [5b8fcf7945] to [1324ab08b0].
1 | /* | < < | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" .globl _OFForward .globl _OFForward_stret .section __TEXT, __objc_methname, cstring_literals str_forwardingTargetForSelector_: .asciz "forwardingTargetForSelector:" .section __DATA, __objc_selrefs, literal_pointers, no_dead_strip sel_forwardingTargetForSelector_: .quad str_forwardingTargetForSelector_ .section __DATA, __objc_imageinfo, regular, no_dead_strip .long 0, 0 .section __TEXT, __text, regular, pure_instructions _OFForward: pushq %rbp movq %rsp, %rbp /* Save all arguments */ subq $0xC0, %rsp /* 16-byte alignment */ movq %rax, -0x8(%rbp) movq %rdi, -0x10(%rbp) movq %rsi, -0x18(%rbp) movq %rdx, -0x20(%rbp) movq %rcx, -0x28(%rbp) movq %r8, -0x30(%rbp) movq %r9, -0x38(%rbp) movaps %xmm0, -0x50(%rbp) movaps %xmm1, -0x60(%rbp) movaps %xmm2, -0x70(%rbp) movaps %xmm3, -0x80(%rbp) movaps %xmm4, -0x90(%rbp) movaps %xmm5, -0xA0(%rbp) movaps %xmm6, -0xB0(%rbp) movaps %xmm7, -0xC0(%rbp) call _object_getClass movq %rax, %rdi movq sel_forwardingTargetForSelector_(%rip), %rsi call _class_respondsToSelector testq %rax, %rax jz 0f movq -0x10(%rbp), %rdi movq sel_forwardingTargetForSelector_(%rip), %rsi movq -0x18(%rbp), %rdx call _objc_msgSend testq %rax, %rax jz 0f cmpq -0x10(%rbp), %rax je 0f movq %rax, %rdi /* Restore all arguments, except %rdi */ movaps -0xC0(%rbp), %xmm7 movaps -0xB0(%rbp), %xmm6 movaps -0xA0(%rbp), %xmm5 movaps -0x90(%rbp), %xmm4 movaps -0x80(%rbp), %xmm3 movaps -0x70(%rbp), %xmm2 movaps -0x60(%rbp), %xmm1 movaps -0x50(%rbp), %xmm0 movq -0x38(%rbp), %r9 movq -0x30(%rbp), %r8 movq -0x28(%rbp), %rcx movq -0x20(%rbp), %rdx movq -0x18(%rbp), %rsi movq -0x8(%rbp), %rax movq %rbp, %rsp popq %rbp jmp _objc_msgSend 0: movq -0x10(%rbp), %rdi movq -0x18(%rbp), %rsi movq %rbp, %rsp popq %rbp jmp _OFMethodNotFound _OFForward_stret: pushq %rbp movq %rsp, %rbp /* Save all arguments */ subq $0xC0, %rsp /* 16-byte alignment */ movq %rax, -0x8(%rbp) movq %rdi, -0x10(%rbp) movq %rsi, -0x18(%rbp) movq %rdx, -0x20(%rbp) movq %rcx, -0x28(%rbp) movq %r8, -0x30(%rbp) movq %r9, -0x38(%rbp) movaps %xmm0, -0x50(%rbp) movaps %xmm1, -0x60(%rbp) movaps %xmm2, -0x70(%rbp) movaps %xmm3, -0x80(%rbp) movaps %xmm4, -0x90(%rbp) movaps %xmm5, -0xA0(%rbp) movaps %xmm6, -0xB0(%rbp) movaps %xmm7, -0xC0(%rbp) movq %rsi, %rdi call _object_getClass movq %rax, %rdi movq sel_forwardingTargetForSelector_(%rip), %rsi call _class_respondsToSelector testq %rax, %rax jz 0f movq -0x18(%rbp), %rdi movq sel_forwardingTargetForSelector_(%rip), %rsi movq -0x20(%rbp), %rdx call _objc_msgSend testq %rax, %rax jz 0f cmpq -0x18(%rbp), %rax je 0f movq %rax, %rsi /* Restore all arguments, except %rsi */ movaps -0xC0(%rbp), %xmm7 movaps -0xB0(%rbp), %xmm6 movaps -0xA0(%rbp), %xmm5 movaps -0x90(%rbp), %xmm4 movaps -0x80(%rbp), %xmm3 movaps -0x70(%rbp), %xmm2 movaps -0x60(%rbp), %xmm1 movaps -0x50(%rbp), %xmm0 movq -0x38(%rbp), %r9 movq -0x30(%rbp), %r8 movq -0x28(%rbp), %rcx movq -0x20(%rbp), %rdx movq -0x10(%rbp), %rdi movq -0x8(%rbp), %rax movq %rbp, %rsp popq %rbp jmp _objc_msgSend_stret 0: movq -0x10(%rbp), %rdi movq -0x18(%rbp), %rsi movq -0x20(%rbp), %rdx movq %rbp, %rsp popq %rbp jmp _OFMethodNotFound_stret |
Modified src/forwarding/forwarding-arm-elf.S from [19985726e9] to [ebb3f926fa].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | #include "platform.h" #ifdef HAVE_VFP2 .fpu vfp #endif | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include "platform.h" #ifdef HAVE_VFP2 .fpu vfp #endif .globl OFForward .globl OFForward_stret .section .text OFForward: #ifdef HAVE_VFP2 vstmdb sp!, {d0-d7} #endif stmfd sp!, {r0-r4, lr} ldr r4, sel_forwardingTargetForSelector_$indirect_.L0 .L0: |
︙ | ︙ | |||
74 75 76 77 78 79 80 | bx r12 0: ldmfd sp!, {r0-r4, lr} #ifdef HAVE_VFP2 vldmia sp!, {d0-d7} #endif | | | | | | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | bx r12 0: ldmfd sp!, {r0-r4, lr} #ifdef HAVE_VFP2 vldmia sp!, {d0-d7} #endif b OFMethodNotFound(PLT) .type OFForward, %function .size OFForward, .-OFForward OFForward_stret: #ifdef HAVE_VFP2 vstmdb sp!, {d0-d7} #endif stmfd sp!, {r0-r4, lr} ldr r4, sel_forwardingTargetForSelector_$indirect_.L1 .L1: |
︙ | ︙ | |||
130 131 132 133 134 135 136 | bx r12 0: ldmfd sp!, {r0-r4, lr} #ifdef HAVE_VFP2 vldmia sp!, {d0-d7} #endif | | | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | bx r12 0: ldmfd sp!, {r0-r4, lr} #ifdef HAVE_VFP2 vldmia sp!, {d0-d7} #endif b OFMethodNotFound_stret(PLT) .type OFForward_stret, %function .size OFForward_stret, .-OFForward_stret init: ldr r0, module$indirect_.L2 .L2: add r0, pc b __objc_exec_class(PLT) |
︙ | ︙ |
Modified src/forwarding/forwarding-arm64-elf.S from [d178718011] to [81775de57c].
1 | /* | < < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" .globl OFForward .globl OFForward_stret .section .text OFForward: OFForward_stret: stp fp, lr, [sp, #-208]! mov fp, sp sub sp, sp, #208 /* Save all arguments, x8 and x19 */ stp x0, x1, [sp] stp x2, x3, [sp, #16] |
︙ | ︙ | |||
94 95 96 97 98 99 100 | 0: ldp x0, x1, [sp] ldr x19, [sp, #72] mov sp, fp ldp fp, lr, [sp], #208 | | | | | | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 0: ldp x0, x1, [sp] ldr x19, [sp, #72] mov sp, fp ldp fp, lr, [sp], #208 b OFMethodNotFound .type OFForward, %function .size OFForward, .-OFForward .type OFForward_stret, %function .size OFForward_stret, .-OFForward_stret init: adrp x0, module add x0, x0, :lo12:module b __objc_exec_class .section .init_array, "aw", %init_array |
︙ | ︙ |
Modified src/forwarding/forwarding-mips-elf.S from [c8fc1f4693] to [e03d5d5039].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" .globl OFForward .globl OFForward_stret #ifdef OF_PIC .macro j_pic symbol lw $t9, %call16(\symbol)($gp) jr $t9 .endm .macro jal_pic symbol lw $t9, %call16(\symbol)($gp) jalr $t9 .endm #else .macro j_pic symbol j \symbol .endm .macro jal_pic symbol jal \symbol .endm #endif .section .text OFForward: #ifdef OF_PIC lui $gp, %hi(_gp_disp) addiu $gp, $gp, %lo(_gp_disp) addu $gp, $gp, $t9 #endif addiu $sp, $sp, -96 |
︙ | ︙ | |||
158 159 160 161 162 163 164 | lw $s1, 24($sp) lw $s0, 20($sp) lw $ra, 16($sp) addiu $sp, $sp, 96 j_pic of_method_not_found | | | | | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | lw $s1, 24($sp) lw $s0, 20($sp) lw $ra, 16($sp) addiu $sp, $sp, 96 j_pic of_method_not_found .type OFForward, %function .size OFForward, .-OFForward OFForward_stret: #ifdef OF_PIC lui $gp, %hi(_gp_disp) addiu $gp, $gp, %lo(_gp_disp) addu $gp, $gp, $t9 #endif addiu $sp, $sp, -96 |
︙ | ︙ | |||
284 285 286 287 288 289 290 | lw $s1, 24($sp) lw $s0, 20($sp) lw $ra, 16($sp) addiu $sp, $sp, 96 j_pic of_method_not_found_stret | | | | 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | lw $s1, 24($sp) lw $s0, 20($sp) lw $ra, 16($sp) addiu $sp, $sp, 96 j_pic of_method_not_found_stret .type OFForward_stret, %function .size OFForward_stret, .-OFForward_stret init: #ifdef OF_PIC lui $gp, %hi(_gp_disp) addiu $gp, $gp, %lo(_gp_disp) addu $gp, $gp, $t9 |
︙ | ︙ |
Modified src/forwarding/forwarding-powerpc-elf.S from [765ed4e505] to [65258e67de].
1 | /* | < < | | | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" .globl OFForward .globl OFForward_stret .section .text OFForward: stwu %r1, -112(%r1) mflr %r0 stw %r0, 116(%r1) #ifdef OF_PIC stw %r30, 104(%r1) bl 0f 0: mflr %r30 addis %r30, %r30, .Lbiased_got2-0b@ha addi %r30, %r30, .Lbiased_got2-0b@l #endif /* Save all arguments */ stw %r3, 8(%r1) stw %r4, 12(%r1) stw %r5, 16(%r1) stw %r6, 20(%r1) stw %r7, 24(%r1) |
︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | stfd %f3, 56(%r1) stfd %f4, 64(%r1) stfd %f5, 72(%r1) stfd %f6, 80(%r1) stfd %f7, 88(%r1) stfd %f8, 96(%r1) bl object_getClass+0x8000@plt lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) bl class_respondsToSelector+0x8000@plt cmpwi %r3, 0 beq- 0f lwz %r3, 8(%r1) lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) bl objc_msg_lookup+0x8000@plt mtctr %r3 lwz %r3, 8(%r1) lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) lwz %r5, 12(%r1) bctrl cmpwi %r3, 0 beq- 0f lwz %r4, 8(%r1) cmpw %r3, %r4 beq- 0f stw %r3, 8(%r1) lwz %r4, 12(%r1) bl objc_msg_lookup+0x8000@plt mtctr %r3 /* Restore all arguments */ lwz %r3, 8(%r1) lwz %r4, 12(%r1) lwz %r5, 16(%r1) lwz %r6, 20(%r1) | > > > > > > > > > > > > > > > > > > > > > > > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | stfd %f3, 56(%r1) stfd %f4, 64(%r1) stfd %f5, 72(%r1) stfd %f6, 80(%r1) stfd %f7, 88(%r1) stfd %f8, 96(%r1) #ifdef OF_PIC bl object_getClass+0x8000@plt lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) bl class_respondsToSelector+0x8000@plt #else bl object_getClass lis %r4, sel_forwardingTargetForSelector_@ha la %r4, sel_forwardingTargetForSelector_@l(%r4) bl class_respondsToSelector #endif cmpwi %r3, 0 beq- 0f lwz %r3, 8(%r1) #ifdef OF_PIC lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) bl objc_msg_lookup+0x8000@plt #else lis %r4, sel_forwardingTargetForSelector_@ha la %r4, sel_forwardingTargetForSelector_@l(%r4) bl objc_msg_lookup #endif mtctr %r3 lwz %r3, 8(%r1) #ifdef OF_PIC lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) #else lis %r4, sel_forwardingTargetForSelector_@ha la %r4, sel_forwardingTargetForSelector_@l(%r4) #endif lwz %r5, 12(%r1) bctrl cmpwi %r3, 0 beq- 0f lwz %r4, 8(%r1) cmpw %r3, %r4 beq- 0f stw %r3, 8(%r1) lwz %r4, 12(%r1) #ifdef OF_PIC bl objc_msg_lookup+0x8000@plt #else bl objc_msg_lookup #endif mtctr %r3 /* Restore all arguments */ lwz %r3, 8(%r1) lwz %r4, 12(%r1) lwz %r5, 16(%r1) lwz %r6, 20(%r1) |
︙ | ︙ | |||
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | lfd %f3, 56(%r1) lfd %f4, 64(%r1) lfd %f5, 72(%r1) lfd %f6, 80(%r1) lfd %f7, 88(%r1) lfd %f8, 96(%r1) lwz %r30, 104(%r1) lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 bctr 0: lwz %r3, 8(%r1) lwz %r4, 12(%r1) | > > > > | < > > > > > > | | | > > | 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | lfd %f3, 56(%r1) lfd %f4, 64(%r1) lfd %f5, 72(%r1) lfd %f6, 80(%r1) lfd %f7, 88(%r1) lfd %f8, 96(%r1) #ifdef OF_PIC lwz %r30, 104(%r1) #endif lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 bctr 0: lwz %r3, 8(%r1) lwz %r4, 12(%r1) #ifdef OF_PIC lwz %r0, .Lgot_OFMethodNotFound-.Lbiased_got2(%r30) mtctr %r0 lwz %r30, 104(%r1) #endif lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 #ifdef OF_PIC bctr #else b OFMethodNotFound #endif .type OFForward, @function .size OFForward, .-OFForward OFForward_stret: stwu %r1, -112(%r1) mflr %r0 stw %r0, 116(%r1) #ifdef OF_PIC stw %r30, 104(%r1) bl 0f 0: mflr %r30 addis %r30, %r30, .Lbiased_got2-0b@ha addi %r30, %r30, .Lbiased_got2-0b@l #endif /* Save all arguments */ stw %r3, 8(%r1) stw %r4, 12(%r1) stw %r5, 16(%r1) stw %r6, 20(%r1) stw %r7, 24(%r1) |
︙ | ︙ | |||
155 156 157 158 159 160 161 | stfd %f4, 64(%r1) stfd %f5, 72(%r1) stfd %f6, 80(%r1) stfd %f7, 88(%r1) stfd %f8, 96(%r1) mr %r3, %r4 | > | > > > > > > > > > > > > > > > > > > > > > > | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | stfd %f4, 64(%r1) stfd %f5, 72(%r1) stfd %f6, 80(%r1) stfd %f7, 88(%r1) stfd %f8, 96(%r1) mr %r3, %r4 #ifdef OF_PIC bl object_getClass+0x8000@plt lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) bl class_respondsToSelector+0x8000@plt #else bl object_getClass lis %r4, sel_forwardingTargetForSelector_@ha la %r4, sel_forwardingTargetForSelector_@l(%r4) bl class_respondsToSelector #endif cmpwi %r3, 0 beq- 0f lwz %r3, 12(%r1) #ifdef OF_PIC lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) bl objc_msg_lookup+0x8000@plt #else lis %r4, sel_forwardingTargetForSelector_@ha la %r4, sel_forwardingTargetForSelector_@l(%r4) bl objc_msg_lookup #endif mtctr %r3 lwz %r3, 12(%r1) #ifdef OF_PIC lwz %r4, .Lgot_sel_forwardingTargetForSelector_-.Lbiased_got2(%r30) #else lis %r4, sel_forwardingTargetForSelector_@ha la %r4, sel_forwardingTargetForSelector_@l(%r4) #endif lwz %r5, 16(%r1) bctrl cmpwi %r3, 0 beq- 0f lwz %r4, 12(%r1) cmpw %r3, %r4 beq- 0f stw %r3, 12(%r1) lwz %r4, 16(%r1) #ifdef OF_PIC bl objc_msg_lookup_stret+0x8000@plt #else bl objc_msg_lookup_stret #endif mtctr %r3 /* Restore all arguments */ lwz %r3, 8(%r1) lwz %r4, 12(%r1) lwz %r5, 16(%r1) lwz %r6, 20(%r1) |
︙ | ︙ | |||
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | lfd %f3, 56(%r1) lfd %f4, 64(%r1) lfd %f5, 72(%r1) lfd %f6, 80(%r1) lfd %f7, 88(%r1) lfd %f8, 96(%r1) lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 bctr 0: lwz %r3, 8(%r1) lwz %r4, 12(%r1) lwz %r5, 16(%r1) | > > > > > | < > > > > > > | | > > > > > > > | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | lfd %f3, 56(%r1) lfd %f4, 64(%r1) lfd %f5, 72(%r1) lfd %f6, 80(%r1) lfd %f7, 88(%r1) lfd %f8, 96(%r1) #ifdef OF_PIC lwz %r30, 104(%r1) #endif lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 bctr 0: lwz %r3, 8(%r1) lwz %r4, 12(%r1) lwz %r5, 16(%r1) #ifdef OF_PIC lwz %r0, .Lgot_OFMethodNotFound_stret-.Lbiased_got2(%r30) mtctr %r0 lwz %r30, 104(%r1) #endif lwz %r0, 116(%r1) mtlr %r0 addi %r1, %r1, 112 #ifdef OF_PIC bctr #else b OFMethodNotFound_stret #endif .type OFForward_stret, @function .size OFForward_stret, .-OFForward_stret init: stwu %r1, -16(%r1) mflr %r0 stw %r0, 20(%r1) #ifdef OF_PIC stw %r30, 8(%r1) bl 0f 0: mflr %r30 addis %r30, %r30, .Lbiased_got2-0b@ha addi %r30, %r30, .Lbiased_got2-0b@l lwz %r3, .Lgot_module-.Lbiased_got2(%r30) bl __objc_exec_class+0x8000@plt lwz %r30, 8(%r1) #else lis %r3, module@ha la %r3, module@l(%r3) bl __objc_exec_class #endif lwz %r0, 20(%r1) addi %r1, %r1, 16 mtlr %r0 blr .section .ctors, "aw", @progbits .long init |
︙ | ︙ | |||
266 267 268 269 270 271 272 273 274 275 276 277 278 | .long 0, sel_forwardingTargetForSelector_ .short 0, 0 .long 0 .long 0 module: .long 8, 16, 0, symtab .section .got2, "aw" .Lbiased_got2 = .+0x8000 .Lgot_module: .long module .Lgot_sel_forwardingTargetForSelector_: .long sel_forwardingTargetForSelector_ | > | | | | > | 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 | .long 0, sel_forwardingTargetForSelector_ .short 0, 0 .long 0 .long 0 module: .long 8, 16, 0, symtab #ifdef OF_PIC .section .got2, "aw" .Lbiased_got2 = .+0x8000 .Lgot_module: .long module .Lgot_sel_forwardingTargetForSelector_: .long sel_forwardingTargetForSelector_ .Lgot_OFMethodNotFound: .long OFMethodNotFound .Lgot_OFMethodNotFound_stret: .long OFMethodNotFound_stret #endif #ifdef OF_LINUX .section .note.GNU-stack, "", @progbits #endif |
Modified src/forwarding/forwarding-sparc-elf.S from [8a7dcec5aa] to [8ec3e64b89].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" .globl OFForward .globl OFForward_stret .section .text OFForward: save %sp, -96, %sp #ifdef OF_PIC sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7 call add_pc add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7 #endif |
︙ | ︙ | |||
75 76 77 78 79 80 81 | call objc_msg_lookup mov %i1, %o1 jmpl %o0, %g0 restore 0: | | | | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | call objc_msg_lookup mov %i1, %o1 jmpl %o0, %g0 restore 0: call OFMethodNotFound restore .type OFForward, %function .size OFForward, .-OFForward OFForward_stret: save %sp, -96, %sp #ifdef OF_PIC sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7 call add_pc add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7 #endif |
︙ | ︙ | |||
136 137 138 139 140 141 142 | call objc_msg_lookup mov %i2, %o1 jmpl %o0, %g0 restore 0: | | | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | call objc_msg_lookup mov %i2, %o1 jmpl %o0, %g0 restore 0: call OFMethodNotFound_stret restore .type OFForward_stret, %function .size OFForward_stret, .-OFForward_stret init: save %sp, -96, %sp #ifdef OF_PIC sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7 call add_pc |
︙ | ︙ |
Modified src/forwarding/forwarding-sparc64-elf.S from [af08d696f6] to [5ae72e6aac].
1 | /* | < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" .globl OFForward .globl OFForward_stret #define BIAS 2047 .section .text OFForward: save %sp, -304, %sp /* * Save all floating point registers as they can be used for parameter * passing. */ std %f0, [%sp + BIAS + 176] |
︙ | ︙ | |||
109 110 111 112 113 114 115 | ldd [%sp + BIAS + 288], %f28 ldd [%sp + BIAS + 296], %f30 jmpl %o0, %g0 restore 0: | | | | | | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | ldd [%sp + BIAS + 288], %f28 ldd [%sp + BIAS + 296], %f30 jmpl %o0, %g0 restore 0: call OFMethodNotFound restore .type OFForward, %function .size OFForward, .-OFForward OFForward_stret: save %sp, -304, %sp /* * Save all floating point registers as they can be used for parameter * passing. */ std %f0, [%sp + BIAS + 176] |
︙ | ︙ | |||
202 203 204 205 206 207 208 | ldd [%sp + BIAS + 288], %f28 ldd [%sp + BIAS + 296], %f30 jmpl %o0, %g0 restore 0: | | | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | ldd [%sp + BIAS + 288], %f28 ldd [%sp + BIAS + 296], %f30 jmpl %o0, %g0 restore 0: call OFMethodNotFound_stret restore .type OFForward_stret, %function .size OFForward_stret, .-OFForward_stret init: save %sp, -176, %sp sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %l7 call add_pc add %l7, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %l7 |
︙ | ︙ |
Modified src/forwarding/forwarding-x86-elf.S from [294c10a12e] to [a55d3f40d7].
1 | /* | < < | < < | | | | | | | | | | | | | | | | | | | | | | > > > > < < < < | | | | | | | | | | | > > < < | | | | | | | | | | | > < | | | | | | | | | | | | | | | | | | | | | | | < < < | > | > > | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" .globl OFForward .globl OFForward_stret .section .text OFForward: pushl %ebp movl %esp, %ebp pushl %ebx subl $20, %esp call get_eip addl $_GLOBAL_OFFSET_TABLE_, %ebx movl 8(%ebp), %eax movl %eax, (%esp) call object_getClass@PLT movl %eax, (%esp) leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax movl %eax, 4(%esp) call class_respondsToSelector@PLT testl %eax, %eax jz 0f movl 8(%ebp), %eax movl %eax, (%esp) leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax movl %eax, 4(%esp) call objc_msg_lookup@PLT movl 8(%ebp), %edx movl %edx, (%esp) leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %edx movl %edx, 4(%esp) movl 12(%ebp), %edx movl %edx, 8(%esp) call *%eax testl %eax, %eax jz 0f cmpl 8(%ebp), %eax je 0f movl %eax, 8(%ebp) movl %eax, (%esp) movl 12(%ebp), %eax movl %eax, 4(%esp) call objc_msg_lookup@PLT addl $20, %esp popl %ebx popl %ebp jmp *%eax 0: leal OFMethodNotFound@GOTOFF(%ebx), %eax addl $20, %esp popl %ebx popl %ebp jmp *%eax .type OFForward, %function .size OFForward, .-OFForward OFForward_stret: pushl %ebp movl %esp, %ebp pushl %ebx subl $20, %esp call get_eip addl $_GLOBAL_OFFSET_TABLE_, %ebx movl 12(%ebp), %eax movl %eax, (%esp) call object_getClass@PLT movl %eax, (%esp) leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax movl %eax, 4(%esp) call class_respondsToSelector@PLT testl %eax, %eax jz 0f movl 12(%ebp), %eax movl %eax, (%esp) leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %eax movl %eax, 4(%esp) call objc_msg_lookup@PLT movl 12(%ebp), %edx movl %edx, (%esp) leal sel_forwardingTargetForSelector_@GOTOFF(%ebx), %edx movl %edx, 4(%esp) movl 16(%ebp), %edx movl %edx, 8(%esp) call *%eax testl %eax, %eax jz 0f cmpl 12(%ebp), %eax je 0f movl %eax, 12(%ebp) movl %eax, (%esp) movl 16(%ebp), %eax movl %eax, 4(%esp) call objc_msg_lookup_stret@PLT addl $20, %esp popl %ebx popl %ebp jmp *%eax 0: leal OFMethodNotFound_stret@GOTOFF(%ebx), %eax addl $20, %esp popl %ebx popl %ebp jmp *%eax .type OFForward_stret, %function .size OFForward_stret, .-OFForward_stret init: pushl %ebp movl %esp, %ebp pushl %ebx subl $4, %esp call get_eip addl $_GLOBAL_OFFSET_TABLE_, %ebx leal module@GOTOFF(%ebx), %eax movl %eax, (%esp) call __objc_exec_class@PLT addl $4, %esp popl %ebx popl %ebp ret get_eip: movl (%esp), %ebx ret #ifdef OF_SOLARIS .section .init_array, "aw" #else .section .ctors, "aw", %progbits #endif |
︙ | ︙ |
Modified src/forwarding/forwarding-x86-win32.S from [38023e4835] to [7c90db9737].
1 | /* | < < | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > | | > | > | < < | | | | | | | | | | | | | | | | | | | | | | > > > | < < | < | | | | | | | | > > > > | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" .globl _OFForward .globl _OFForward_stret .section .text _OFForward: pushl %ebp movl %esp, %ebp pushl %ebx subl $20, %esp movl 8(%ebp), %eax movl %eax, (%esp) call _object_getClass movl %eax, (%esp) movl $sel_forwardingTargetForSelector_, %eax movl %eax, 4(%esp) call _class_respondsToSelector testl %eax, %eax jz 0f movl 8(%ebp), %eax movl %eax, (%esp) movl $sel_forwardingTargetForSelector_, %eax movl %eax, 4(%esp) call _objc_msg_lookup movl 8(%ebp), %edx movl %edx, (%esp) movl $sel_forwardingTargetForSelector_, %edx movl %edx, 4(%esp) movl 12(%ebp), %edx movl %edx, 8(%esp) call *%eax testl %eax, %eax jz 0f cmpl 8(%ebp), %eax je 0f movl %eax, 8(%ebp) movl %eax, (%esp) movl 12(%ebp), %eax movl %eax, 4(%esp) call _objc_msg_lookup addl $20, %esp popl %ebx popl %ebp jmp *%eax 0: addl $20, %esp popl %ebx popl %ebp jmp _OFMethodNotFound .def _OFForward .scl 2 .type 32 .endef _OFForward_stret: pushl %ebp movl %esp, %ebp pushl %ebx subl $20, %esp movl 12(%ebp), %eax movl %eax, (%esp) call _object_getClass movl %eax, (%esp) movl $sel_forwardingTargetForSelector_, %eax movl %eax, 4(%esp) call _class_respondsToSelector testl %eax, %eax jz 0f movl 12(%ebp), %eax movl %eax, (%esp) movl $sel_forwardingTargetForSelector_, %eax movl %eax, 4(%esp) call _objc_msg_lookup movl 12(%ebp), %edx movl %edx, (%esp) movl $sel_forwardingTargetForSelector_, %edx movl %edx, 4(%esp) movl 16(%ebp), %edx movl %edx, 8(%esp) call *%eax testl %eax, %eax jz 0f cmpl 12(%ebp), %eax je 0f movl %eax, 12(%ebp) movl %eax, (%esp) movl 16(%ebp), %eax movl %eax, 4(%esp) call _objc_msg_lookup_stret addl $20, %esp popl %ebx popl %ebp jmp *%eax 0: addl $20, %esp popl %ebx popl %ebp jmp _OFMethodNotFound_stret .def _OFForward_stret .scl 2 .type 32 .endef init: pushl %ebp movl %esp, %ebp pushl %ebx subl $4, %esp movl $module, %eax movl %eax, (%esp) call ___objc_exec_class addl $4, %esp popl %ebx popl %ebp ret .section .ctors, "aw" .long init .section .rodata str_forwardingTargetForSelector_: |
︙ | ︙ |
Modified src/forwarding/forwarding-x86_64-elf.S from [1d1fc641cf] to [9ea0cb41b3].
1 | /* | < < | < < | | | | | | | | | | | | | | | | > | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < > > > | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" .globl OFForward .globl OFForward_stret .section .text OFForward: pushq %rbp movq %rsp, %rbp /* Save all arguments */ subq $0xC0, %rsp /* 16-byte alignment */ movq %rax, -0x8(%rbp) movq %rdi, -0x10(%rbp) movq %rsi, -0x18(%rbp) movq %rdx, -0x20(%rbp) movq %rcx, -0x28(%rbp) movq %r8, -0x30(%rbp) movq %r9, -0x38(%rbp) movaps %xmm0, -0x50(%rbp) movaps %xmm1, -0x60(%rbp) movaps %xmm2, -0x70(%rbp) movaps %xmm3, -0x80(%rbp) movaps %xmm4, -0x90(%rbp) movaps %xmm5, -0xA0(%rbp) movaps %xmm6, -0xB0(%rbp) movaps %xmm7, -0xC0(%rbp) call object_getClass@PLT movq %rax, %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi call class_respondsToSelector@PLT testq %rax, %rax jz 0f movq -0x10(%rbp), %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi call objc_msg_lookup@PLT movq -0x10(%rbp), %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi movq -0x18(%rbp), %rdx call *%rax testq %rax, %rax jz 0f cmpq -0x10(%rbp), %rax je 0f movq %rax, -0x10(%rbp) movq %rax, %rdi movq -0x18(%rbp), %rsi call objc_msg_lookup@PLT movq %rax, %r11 /* Restore all arguments */ movaps -0xC0(%rbp), %xmm7 movaps -0xB0(%rbp), %xmm6 movaps -0xA0(%rbp), %xmm5 movaps -0x90(%rbp), %xmm4 movaps -0x80(%rbp), %xmm3 movaps -0x70(%rbp), %xmm2 movaps -0x60(%rbp), %xmm1 movaps -0x50(%rbp), %xmm0 movq -0x38(%rbp), %r9 movq -0x30(%rbp), %r8 movq -0x28(%rbp), %rcx movq -0x20(%rbp), %rdx movq -0x18(%rbp), %rsi movq -0x10(%rbp), %rdi movq -0x8(%rbp), %rax movq %rbp, %rsp popq %rbp jmpq *%r11 0: movq -0x10(%rbp), %rdi movq -0x18(%rbp), %rsi movq %rbp, %rsp popq %rbp jmp OFMethodNotFound@PLT .type OFForward, %function .size OFForward, .-OFForward OFForward_stret: pushq %rbp movq %rsp, %rbp /* Save all arguments */ subq $0xC0, %rsp /* 16-byte alignment */ movq %rax, -0x8(%rbp) movq %rdi, -0x10(%rbp) movq %rsi, -0x18(%rbp) movq %rdx, -0x20(%rbp) movq %rcx, -0x28(%rbp) movq %r8, -0x30(%rbp) movq %r9, -0x38(%rbp) movaps %xmm0, -0x50(%rbp) movaps %xmm1, -0x60(%rbp) movaps %xmm2, -0x70(%rbp) movaps %xmm3, -0x80(%rbp) movaps %xmm4, -0x90(%rbp) movaps %xmm5, -0xA0(%rbp) movaps %xmm6, -0xB0(%rbp) movaps %xmm7, -0xC0(%rbp) movq %rsi, %rdi call object_getClass@PLT movq %rax, %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi call class_respondsToSelector@PLT testq %rax, %rax jz 0f movq -0x18(%rbp), %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi call objc_msg_lookup@PLT movq -0x18(%rbp), %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi movq -0x20(%rbp), %rdx call *%rax testq %rax, %rax jz 0f cmpq -0x18(%rbp), %rax je 0f movq %rax, -0x18(%rbp) movq %rax, %rdi movq -0x20(%rbp), %rsi call objc_msg_lookup_stret@PLT movq %rax, %r11 /* Restore all arguments */ movaps -0xC0(%rbp), %xmm7 movaps -0xB0(%rbp), %xmm6 movaps -0xA0(%rbp), %xmm5 movaps -0x90(%rbp), %xmm4 movaps -0x80(%rbp), %xmm3 movaps -0x70(%rbp), %xmm2 movaps -0x60(%rbp), %xmm1 movaps -0x50(%rbp), %xmm0 movq -0x38(%rbp), %r9 movq -0x30(%rbp), %r8 movq -0x28(%rbp), %rcx movq -0x20(%rbp), %rdx movq -0x18(%rbp), %rsi movq -0x10(%rbp), %rdi movq -0x8(%rbp), %rax movq %rbp, %rsp popq %rbp jmpq *%r11 0: movq -0x10(%rbp), %rdi movq -0x18(%rbp), %rsi movq -0x20(%rbp), %rdx movq %rbp, %rsp popq %rbp jmp OFMethodNotFound_stret@PLT .type OFForward_stret, %function .size OFForward_stret, .-OFForward_stret init: leaq module(%rip), %rdi jmp __objc_exec_class@PLT #ifdef OF_SOLARIS .section .init_array, "aw" #else .section .ctors, "aw", %progbits #endif |
︙ | ︙ |
Modified src/forwarding/forwarding-x86_64-macho.S from [4631e2d50d] to [0e975fcfd2].
1 | /* | < < | < < | | | | | | | | | | | | | | | | > | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | > | | | | | | | | | | < < > > | | | | | | | | | | | | | | | < < < < > > > > | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" .globl _OFForward .globl _OFForward_stret .section __TEXT, __text, regular, pure_instructions _OFForward: pushq %rbp movq %rsp, %rbp /* Save all arguments */ subq $0xC0, %rsp /* 16-byte alignment */ movq %rax, -0x8(%rbp) movq %rdi, -0x10(%rbp) movq %rsi, -0x18(%rbp) movq %rdx, -0x20(%rbp) movq %rcx, -0x28(%rbp) movq %r8, -0x30(%rbp) movq %r9, -0x38(%rbp) movaps %xmm0, -0x50(%rbp) movaps %xmm1, -0x60(%rbp) movaps %xmm2, -0x70(%rbp) movaps %xmm3, -0x80(%rbp) movaps %xmm4, -0x90(%rbp) movaps %xmm5, -0xA0(%rbp) movaps %xmm6, -0xB0(%rbp) movaps %xmm7, -0xC0(%rbp) call _object_getClass movq %rax, %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi call _class_respondsToSelector testq %rax, %rax jz 0f movq -0x10(%rbp), %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi call _objc_msg_lookup movq -0x10(%rbp), %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi movq -0x18(%rbp), %rdx call *%rax testq %rax, %rax jz 0f cmpq -0x10(%rbp), %rax je 0f movq %rax, -0x10(%rbp) movq %rax, %rdi movq -0x18(%rbp), %rsi call _objc_msg_lookup movq %rax, %r11 /* Restore all arguments */ movaps -0xC0(%rbp), %xmm7 movaps -0xB0(%rbp), %xmm6 movaps -0xA0(%rbp), %xmm5 movaps -0x90(%rbp), %xmm4 movaps -0x80(%rbp), %xmm3 movaps -0x70(%rbp), %xmm2 movaps -0x60(%rbp), %xmm1 movaps -0x50(%rbp), %xmm0 movq -0x38(%rbp), %r9 movq -0x30(%rbp), %r8 movq -0x28(%rbp), %rcx movq -0x20(%rbp), %rdx movq -0x18(%rbp), %rsi movq -0x10(%rbp), %rdi movq -0x8(%rbp), %rax movq %rbp, %rsp popq %rbp jmpq *%r11 0: movq -0x10(%rbp), %rdi movq -0x18(%rbp), %rsi movq %rbp, %rsp popq %rbp jmp _OFMethodNotFound _OFForward_stret: pushq %rbp movq %rsp, %rbp /* Save all arguments */ subq $0xC0, %rsp /* 16-byte alignment */ movq %rax, -0x8(%rbp) movq %rdi, -0x10(%rbp) movq %rsi, -0x18(%rbp) movq %rdx, -0x20(%rbp) movq %rcx, -0x28(%rbp) movq %r8, -0x30(%rbp) movq %r9, -0x38(%rbp) movaps %xmm0, -0x50(%rbp) movaps %xmm1, -0x60(%rbp) movaps %xmm2, -0x70(%rbp) movaps %xmm3, -0x80(%rbp) movaps %xmm4, -0x90(%rbp) movaps %xmm5, -0xA0(%rbp) movaps %xmm6, -0xB0(%rbp) movaps %xmm7, -0xC0(%rbp) movq %rsi, %rdi call _object_getClass movq %rax, %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi call _class_respondsToSelector testq %rax, %rax jz 0f movq -0x18(%rbp), %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi call _objc_msg_lookup movq -0x18(%rbp), %rdi leaq sel_forwardingTargetForSelector_(%rip), %rsi movq -0x20(%rbp), %rdx call *%rax testq %rax, %rax jz 0f cmpq -0x18(%rbp), %rax je 0f movq %rax, -0x18(%rbp) movq %rax, %rdi movq -0x20(%rbp), %rsi call _objc_msg_lookup_stret movq %rax, %r11 /* Restore all arguments */ movaps -0xC0(%rbp), %xmm7 movaps -0xB0(%rbp), %xmm6 movaps -0xA0(%rbp), %xmm5 movaps -0x90(%rbp), %xmm4 movaps -0x80(%rbp), %xmm3 movaps -0x70(%rbp), %xmm2 movaps -0x60(%rbp), %xmm1 movaps -0x50(%rbp), %xmm0 movq -0x38(%rbp), %r9 movq -0x30(%rbp), %r8 movq -0x28(%rbp), %rcx movq -0x20(%rbp), %rdx movq -0x18(%rbp), %rsi movq -0x10(%rbp), %rdi movq -0x8(%rbp), %rax movq %rbp, %rsp popq %rbp jmpq *%r11 0: movq -0x10(%rbp), %rdi movq -0x18(%rbp), %rsi movq -0x20(%rbp), %rdx movq %rbp, %rsp popq %rbp jmp _OFMethodNotFound_stret init: leaq module(%rip), %rdi jmp ___objc_exec_class .section __DATA, __mod_init_func, mod_init_funcs .quad init .section __TEXT, __cstring, cstring_literals str_forwardingTargetForSelector_: |
︙ | ︙ |
Modified src/forwarding/forwarding-x86_64-win64.S from [b1b62864b4] to [74c1db404c].
1 | /* | < < | < < | | | | | | | | | | | | | | | | | | | | | | | | | > > < < | | | | | | | | | | | | | | | < > | | | | | | | | > > > > | | | | | | | | | | | | | | > | < | | | | | | | | | | | | | | | | | | | | | | | | | > | > < < | | | | | | | | > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" .globl OFForward .globl OFForward_stret .section .text OFForward: pushq %rbp movq %rsp, %rbp /* Save all arguments */ subq $0x90, %rsp /* 16-byte alignment */ movq %rax, -0x28(%rbp) movq %rcx, -0x30(%rbp) movq %rdx, -0x38(%rbp) movq %r8, -0x40(%rbp) movq %r9, -0x48(%rbp) movaps %xmm0, -0x60(%rbp) movaps %xmm1, -0x70(%rbp) movaps %xmm2, -0x80(%rbp) movaps %xmm3, -0x90(%rbp) call object_getClass movq %rax, %rcx leaq sel_forwardingTargetForSelector_(%rip), %rdx call class_respondsToSelector testq %rax, %rax jz 0f movq -0x30(%rbp), %rcx leaq sel_forwardingTargetForSelector_(%rip), %rdx call objc_msg_lookup movq -0x30(%rbp), %rcx leaq sel_forwardingTargetForSelector_(%rip), %rdx movq -0x38(%rbp), %r8 call *%rax testq %rax, %rax jz 0f cmpq -0x30(%rbp), %rax je 0f movq %rax, -0x30(%rbp) movq %rax, %rcx movq -0x38(%rbp), %rdx call objc_msg_lookup movq %rax, %r11 /* Restore all arguments */ movaps -0x90(%rbp), %xmm3 movaps -0x80(%rbp), %xmm2 movaps -0x70(%rbp), %xmm1 movaps -0x60(%rbp), %xmm0 movq -0x48(%rbp), %r9 movq -0x40(%rbp), %r8 movq -0x38(%rbp), %rdx movq -0x30(%rbp), %rcx movq -0x28(%rbp), %rax movq %rbp, %rsp popq %rbp jmpq *%r11 0: movq -0x30(%rbp), %rcx movq -0x38(%rbp), %rdx movq %rbp, %rsp popq %rbp jmp OFMethodNotFound .def OFForward .scl 2 .type 32 .endef OFForward_stret: pushq %rbp movq %rsp, %rbp /* Save all arguments */ subq $0x90, %rsp /* 16-byte alignment */ movq %rax, -0x28(%rbp) movq %rcx, -0x30(%rbp) movq %rdx, -0x38(%rbp) movq %r8, -0x40(%rbp) movq %r9, -0x48(%rbp) movaps %xmm0, -0x60(%rbp) movaps %xmm1, -0x70(%rbp) movaps %xmm2, -0x80(%rbp) movaps %xmm3, -0x90(%rbp) movq %rdx, %rcx call object_getClass movq %rax, %rcx leaq sel_forwardingTargetForSelector_(%rip), %rdx call class_respondsToSelector testq %rax, %rax jz 0f movq -0x38(%rbp), %rcx leaq sel_forwardingTargetForSelector_(%rip), %rdx call objc_msg_lookup movq -0x38(%rbp), %rcx leaq sel_forwardingTargetForSelector_(%rip), %rdx movq -0x40(%rbp), %r8 call *%rax testq %rax, %rax jz 0f cmpq -0x38(%rbp), %rax je 0f movq %rax, -0x38(%rbp) movq %rax, %rcx movq -0x40(%rbp), %rdx call objc_msg_lookup_stret movq %rax, %r11 /* Restore all arguments */ movaps -0x90(%rbp), %xmm3 movaps -0x80(%rbp), %xmm2 movaps -0x70(%rbp), %xmm1 movaps -0x60(%rbp), %xmm0 movq -0x48(%rbp), %r9 movq -0x40(%rbp), %r8 movq -0x38(%rbp), %rdx movq -0x30(%rbp), %rcx movq -0x28(%rbp), %rax movq %rbp, %rsp popq %rbp jmpq *%r11 0: movq -0x30(%rbp), %rcx movq -0x38(%rbp), %rdx movq -0x40(%rbp), %r8 movq %rbp, %rsp popq %rbp jmp OFMethodNotFound_stret .def OFForward_stret .scl 2 .type 32 .endef init: leaq module(%rip), %rcx jmp __objc_exec_class .section .ctors, "aw" .quad init .section .rodata str_forwardingTargetForSelector_: |
︙ | ︙ |
Modified src/forwarding/forwarding.S from [873a2fafd1] to [0a5e45dea8].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Deleted src/invocation/Makefile version [a7afc8dd3a].
|
| < < < < < < < < < < < < |
Deleted src/invocation/apple-call-x86_64.S version [3884ee11f3].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/invocation/call-x86_64-elf.S version [10e2914d71].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/invocation/call.S version [94426b7ab0].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/invocation/invoke-x86_64.h version [e748f149fa].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/invocation/invoke-x86_64.m version [ab1dc9bdb2].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/invocation/invoke.m version [619adef304].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/libbases.m from [6db9ec2780] to [952ca43ba1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified src/macros.h from [43e7dc4d8f] to [60a41b82a1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif #include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> | > | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #ifndef __STDC_LIMIT_MACROS # define __STDC_LIMIT_MACROS #endif #ifndef __STDC_CONSTANT_MACROS # define __STDC_CONSTANT_MACROS #endif #include <limits.h> #include <stdbool.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
99 100 101 102 103 104 105 | # define OF_LIKELY(cond) (cond) # define OF_UNLIKELY(cond) (cond) # define OF_CONST_FUNC # define OF_NO_RETURN_FUNC # define OF_WEAK_REF(sym) #endif | < < < < < < | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | # define OF_LIKELY(cond) (cond) # define OF_UNLIKELY(cond) (cond) # define OF_CONST_FUNC # define OF_NO_RETURN_FUNC # define OF_WEAK_REF(sym) #endif #if __STDC_VERSION__ >= 201112L # define OF_ALIGNOF(type) _Alignof(type) # define OF_ALIGNAS(type) _Alignas(type) #else # define OF_ALIGNOF(type) __alignof__(type) # define OF_ALIGNAS(type) __attribute__((__aligned__(__alignof__(type)))) #endif |
︙ | ︙ | |||
144 145 146 147 148 149 150 151 152 153 154 155 156 157 | #endif #ifdef __GNUC__ # define OF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) #else # define OF_GCC_VERSION 0 #endif #ifndef __has_feature # define __has_feature(x) 0 #endif #ifndef __has_attribute # define __has_attribute(x) 0 | > > > | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | #endif #ifdef __GNUC__ # define OF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) #else # define OF_GCC_VERSION 0 #endif #define OF_STRINGIFY(s) OF_STRINGIFY2(s) #define OF_STRINGIFY2(s) #s #ifndef __has_feature # define __has_feature(x) 0 #endif #ifndef __has_attribute # define __has_attribute(x) 0 |
︙ | ︙ | |||
256 257 258 259 260 261 262 | # define OF_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) #else # define OF_WARN_UNUSED_RESULT #endif #if __has_attribute(__unavailable__) # define OF_UNAVAILABLE __attribute__((__unavailable__)) | < | 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | # define OF_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) #else # define OF_WARN_UNUSED_RESULT #endif #if __has_attribute(__unavailable__) # define OF_UNAVAILABLE __attribute__((__unavailable__)) #else # define OF_UNAVAILABLE #endif #if __has_attribute(__objc_requires_super__) # define OF_REQUIRES_SUPER __attribute__((__objc_requires_super__)) #else |
︙ | ︙ | |||
316 317 318 319 320 321 322 | #endif #if __has_attribute(__objc_direct_members__) && defined(OF_APPLE_RUNTIME) # define OF_DIRECT_MEMBERS __attribute__((__objc_direct_members__)) #else # define OF_DIRECT_MEMBERS #endif | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | #endif #if __has_attribute(__objc_direct_members__) && defined(OF_APPLE_RUNTIME) # define OF_DIRECT_MEMBERS __attribute__((__objc_direct_members__)) #else # define OF_DIRECT_MEMBERS #endif #ifdef OF_APPLE_RUNTIME # if defined(OF_X86_64) || defined(OF_X86) || defined(OF_ARM64) || \ defined(OF_ARM) || defined(OF_POWERPC) # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET # endif #else |
︙ | ︙ | |||
385 386 387 388 389 390 391 | # if __OBJFW_RUNTIME_ABI__ >= 800 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET # endif # endif # endif #endif | < | > | > > > > > > > > | > | | | | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | # if __OBJFW_RUNTIME_ABI__ >= 800 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET # endif # endif # endif #endif #define OFMaxRetainCount UINT_MAX #ifdef OBJC_COMPILING_RUNTIME # define OFEnsure(cond) \ do { \ if OF_UNLIKELY (!(cond)) \ objc_error("ObjFWRT @ " __FILE__ ":" \ OF_STRINGIFY(__LINE__), \ "Failed to ensure condition:\n" #cond); \ } while(0) #else # define OFEnsure(cond) \ do { \ if OF_UNLIKELY (!(cond)) { \ fprintf(stderr, "Failed to ensure condition " \ "in " __FILE__ ":%d:\n" #cond "\n", \ __LINE__); \ abort(); \ } \ } while (0) #endif #define OF_UNRECOGNIZED_SELECTOR OFMethodNotFound(self, _cmd); #if __has_feature(objc_arc) # define OF_INVALID_INIT_METHOD OFMethodNotFound(self, _cmd); #else # define OF_INVALID_INIT_METHOD \ @try { \ OFMethodNotFound(self, _cmd); \ } @catch (id e) { \ [self release]; \ @throw e; \ } \ \ abort(); #endif |
︙ | ︙ | |||
438 439 440 441 442 443 444 | static void __attribute__((__constructor__(prio))) \ OF_PREPROCESSOR_CONCAT(constructor, __LINE__)(void) #define OF_DESTRUCTOR(prio) \ static void __attribute__((__destructor__(prio))) \ OF_PREPROCESSOR_CONCAT(destructor, __LINE__)(void) static OF_INLINE uint16_t OF_CONST_FUNC | | | | | > | > | > | | > | > | > | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | | > > > | | | > > > > > > | | | > > > | | | | | > > | | > > > > | | > > | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | > | < < < < < < < < < < < < < < < < < < < < < < | | > > > | < < < | | | < < < < < < < < < < < < < < | | | | | | | | | | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 | static void __attribute__((__constructor__(prio))) \ OF_PREPROCESSOR_CONCAT(constructor, __LINE__)(void) #define OF_DESTRUCTOR(prio) \ static void __attribute__((__destructor__(prio))) \ OF_PREPROCESSOR_CONCAT(destructor, __LINE__)(void) static OF_INLINE uint16_t OF_CONST_FUNC OFByteSwap16Const(uint16_t i) { return (i & UINT16_C(0xFF00)) >> 8 | (i & UINT16_C(0x00FF)) << 8; } static OF_INLINE uint32_t OF_CONST_FUNC OFByteSwap32Const(uint32_t i) { return (i & UINT32_C(0xFF000000)) >> 24 | (i & UINT32_C(0x00FF0000)) >> 8 | (i & UINT32_C(0x0000FF00)) << 8 | (i & UINT32_C(0x000000FF)) << 24; } static OF_INLINE uint64_t OF_CONST_FUNC OFByteSwap64Const(uint64_t i) { return (i & UINT64_C(0xFF00000000000000)) >> 56 | (i & UINT64_C(0x00FF000000000000)) >> 40 | (i & UINT64_C(0x0000FF0000000000)) >> 24 | (i & UINT64_C(0x000000FF00000000)) >> 8 | (i & UINT64_C(0x00000000FF000000)) << 8 | (i & UINT64_C(0x0000000000FF0000)) << 24 | (i & UINT64_C(0x000000000000FF00)) << 40 | (i & UINT64_C(0x00000000000000FF)) << 56; } static OF_INLINE uint16_t OF_CONST_FUNC OFByteSwap16NonConst(uint16_t i) { #if defined(OF_HAVE_BUILTIN_BSWAP16) return __builtin_bswap16(i); #elif (defined(OF_X86_64) || defined(OF_X86)) && defined(__GNUC__) __asm__ ( "xchgb %h0, %b0" : "=Q"(i) : "0"(i) ); #elif defined(OF_POWERPC) && defined(__GNUC__) __asm__ ( "lhbrx %0, 0, %1" : "=r"(i) : "r"(&i), "m"(i) ); #elif defined(OF_ARMV6) && defined(__GNUC__) __asm__ ( "rev16 %0, %0" : "=r"(i) : "0"(i) ); #else i = (i & UINT16_C(0xFF00)) >> 8 | (i & UINT16_C(0x00FF)) << 8; #endif return i; } static OF_INLINE uint32_t OF_CONST_FUNC OFByteSwap32NonConst(uint32_t i) { #if defined(OF_HAVE_BUILTIN_BSWAP32) return __builtin_bswap32(i); #elif (defined(OF_X86_64) || defined(OF_X86)) && defined(__GNUC__) __asm__ ( "bswap %0" : "=q"(i) : "0"(i) ); #elif defined(OF_POWERPC) && defined(__GNUC__) __asm__ ( "lwbrx %0, 0, %1" : "=r"(i) : "r"(&i), "m"(i) ); #elif defined(OF_ARMV6) && defined(__GNUC__) __asm__ ( "rev %0, %0" : "=r"(i) : "0"(i) ); #else i = (i & UINT32_C(0xFF000000)) >> 24 | (i & UINT32_C(0x00FF0000)) >> 8 | (i & UINT32_C(0x0000FF00)) << 8 | (i & UINT32_C(0x000000FF)) << 24; #endif return i; } static OF_INLINE uint64_t OF_CONST_FUNC OFByteSwap64NonConst(uint64_t i) { #if defined(OF_HAVE_BUILTIN_BSWAP64) return __builtin_bswap64(i); #elif defined(OF_X86_64) && defined(__GNUC__) __asm__ ( "bswap %0" : "=r"(i) : "0"(i) ); #elif defined(OF_X86) && defined(__GNUC__) __asm__ ( "bswap %%eax\n\t" "bswap %%edx\n\t" "xchgl %%eax, %%edx" : "=A"(i) : "0"(i) ); #else i = (uint64_t)OFByteSwap32NonConst( (uint32_t)(i & UINT32_C(0xFFFFFFFF))) << 32 | OFByteSwap32NonConst((uint32_t)(i >> 32)); #endif return i; } #ifdef __GNUC__ # define OFByteSwap16(i) \ (__builtin_constant_p(i) ? OFByteSwap16Const(i) : OFByteSwap16NonConst(i)) # define OFByteSwap32(i) \ (__builtin_constant_p(i) ? OFByteSwap32Const(i) : OFByteSwap32NonConst(i)) # define OFByteSwap64(i) \ (__builtin_constant_p(i) ? OFByteSwap64Const(i) : OFByteSwap64NonConst(i)) #else # define OFByteSwap16(i) OFByteSwap16Const(i) # define OFByteSwap32(i) OFByteSwap32Const(i) # define OFByteSwap64(i) OFByteSwap64Const(i) #endif static OF_INLINE uint32_t OFFloatToRawUInt32(float f) { uint32_t ret; memcpy(&ret, &f, 4); return ret; } static OF_INLINE float OFRawUInt32ToFloat(uint32_t uInt32) { float ret; memcpy(&ret, &uInt32, 4); return ret; } static OF_INLINE uint64_t OFDoubleToRawUInt64(double d) { uint64_t ret; memcpy(&ret, &d, 8); return ret; } static OF_INLINE double OFRawUInt64ToDouble(uint64_t uInt64) { double ret; memcpy(&ret, &uInt64, 8); return ret; } static OF_INLINE float OF_CONST_FUNC OFByteSwapFloat(float f) { return OFRawUInt32ToFloat(OFByteSwap32(OFFloatToRawUInt32(f))); } static OF_INLINE double OF_CONST_FUNC OFByteSwapDouble(double d) { return OFRawUInt64ToDouble(OFByteSwap64(OFDoubleToRawUInt64(d))); } #ifdef OF_BIG_ENDIAN # define OFFromBigEndian16(i) (i) # define OFFromBigEndian32(i) (i) # define OFFromBigEndian64(i) (i) # define OFFromLittleEndian16(i) OFByteSwap16(i) # define OFFromLittleEndian32(i) OFByteSwap32(i) # define OFFromLittleEndian64(i) OFByteSwap64(i) # define OFToBigEndian16(i) (i) # define OFToBigEndian32(i) (i) # define OFToBigEndian64(i) (i) # define OFToLittleEndian16(i) OFByteSwap16(i) # define OFToLittleEndian32(i) OFByteSwap32(i) # define OFToLittleEndian64(i) OFByteSwap64(i) #else # define OFFromBigEndian16(i) OFByteSwap16(i) # define OFFromBigEndian32(i) OFByteSwap32(i) # define OFFromBigEndian64(i) OFByteSwap64(i) # define OFFromLittleEndian16(i) (i) # define OFFromLittleEndian32(i) (i) # define OFFromLittleEndian64(i) (i) # define OFToBigEndian16(i) OFByteSwap16(i) # define OFToBigEndian32(i) OFByteSwap32(i) # define OFToBigEndian64(i) OFByteSwap64(i) # define OFToLittleEndian16(i) (i) # define OFToLittleEndian32(i) (i) # define OFToLittleEndian64(i) (i) #endif #ifdef OF_FLOAT_BIG_ENDIAN # define OFFromBigEndianFloat(f) (f) # define OFFromBigEndianDouble(d) (d) # define OFFromLittleEndianFloat(f) OFByteSwapFloat(f) # define OFFromLittleEndianDouble(d) OFByteSwapDouble(d) # define OFToBigEndianFloat(f) (f) # define OFToBigEndianDouble(d) (d) # define OFToLittleEndianFloat(f) OFByteSwapFloat(f) # define OFToLittleEndianDouble(d) OFByteSwapDouble(d) #else # define OFFromBigEndianFloat(f) OFByteSwapFloat(f) # define OFFromBigEndianDouble(d) OFByteSwapDouble(d) # define OFFromLittleEndianFloat(f) (f) # define OFFromLittleEndianDouble(d) (d) # define OFToBigEndianFloat(f) OFByteSwapFloat(f) # define OFToBigEndianDouble(d) OFByteSwapDouble(d) # define OFToLittleEndianFloat(f) (f) # define OFToLittleEndianDouble(d) (d) #endif #define OFRotateLeft(value, bits) \ (((bits) % (sizeof(value) * 8)) > 0 \ ? ((value) << ((bits) % (sizeof(value) * 8))) | \ ((value) >> (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \ : (value)) #define OFRotateRight(value, bits) \ (((bits) % (sizeof(value) * 8)) > 0 \ ? ((value) >> ((bits) % (sizeof(value) * 8))) | \ ((value) << (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \ : (value)) #define OFRoundUpToPowerOf2(pow2, value) \ (((value) + (pow2) - 1) & ~((pow2) - 1)) static OF_INLINE bool OFBitsetIsSet(unsigned char *_Nonnull storage, size_t idx) { return storage[idx / CHAR_BIT] & (1u << (idx % CHAR_BIT)); } static OF_INLINE void OFBitsetSet(unsigned char *_Nonnull storage, size_t idx) { storage[idx / CHAR_BIT] |= (1u << (idx % CHAR_BIT)); } static OF_INLINE void OFBitsetClear(unsigned char *_Nonnull storage, size_t idx) { storage[idx / CHAR_BIT] &= ~(1u << (idx % CHAR_BIT)); } static OF_INLINE void OFZeroMemory(void *_Nonnull buffer_, size_t length) { volatile unsigned char *buffer = (volatile unsigned char *)buffer_; while (buffer < (unsigned char *)buffer_ + length) *buffer++ = '\0'; } static OF_INLINE bool OFASCIIIsAlpha(char c) { return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); } static OF_INLINE bool OFASCIIIsDigit(char c) { return (c >= '0' && c <= '9'); } static OF_INLINE bool OFASCIIIsAlnum(char c) { return (OFASCIIIsAlpha(c) || OFASCIIIsDigit(c)); } static OF_INLINE bool OFASCIIIsSpace(char c) { return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v'); } static OF_INLINE char OFASCIIToUpper(char c) { return (c >= 'a' && c <= 'z' ? 'A' + (c - 'a') : c); } static OF_INLINE char OFASCIIToLower(char c) { return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c); } #endif |
Modified src/module.modulemap from [46be0ed236] to [33c24fc753].
1 2 3 4 | framework module ObjFW { umbrella header "ObjFW.h" /* | | | | | | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | framework module ObjFW { umbrella header "ObjFW.h" /* * These are included by OFAtomic.h, but should never be included * directly. */ exclude header "platform/GCC4/OFAtomic.h" exclude header "platform/GCC4.7/OFAtomic.h" exclude header "platform/PowerPC/OFAtomic.h" exclude header "platform/macOS/OFAtomic.h" exclude header "platform/x86/OFAtomic.h" export * } |
Modified src/objfw-defs.h.in from [4530c4317b] to [69a2e4862c].
|
| < < < > < | > > < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #undef OF_APPLE_RUNTIME #undef OF_BIG_ENDIAN #undef OF_FLOAT_BIG_ENDIAN #undef OF_HAVE_AFUNIX_H #undef OF_HAVE_ATOMIC_BUILTINS #undef OF_HAVE_ATOMIC_OPS #undef OF_HAVE_BUILTIN_BSWAP16 #undef OF_HAVE_BUILTIN_BSWAP32 #undef OF_HAVE_BUILTIN_BSWAP64 #undef OF_HAVE_CHMOD #undef OF_HAVE_CHOWN #undef OF_HAVE_FILES #undef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR #undef OF_HAVE_IPV6 #undef OF_HAVE_IPX #undef OF_HAVE_LIMITS_H #undef OF_HAVE_LINK #undef OF_HAVE_MAX_ALIGN_T #undef OF_HAVE_NETINET_IN_H #undef OF_HAVE_NETINET_TCP_H #undef OF_HAVE_NETIPX_IPX_H #undef OF_HAVE_OSATOMIC #undef OF_HAVE_OSATOMIC_64 #undef OF_HAVE_PIPE #undef OF_HAVE_PLEDGE #undef OF_HAVE_PLUGINS #undef OF_HAVE_SUBPROCESSES #undef OF_HAVE_PTHREADS #undef OF_HAVE_PTHREAD_SPINLOCKS #undef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES #undef OF_HAVE_SCHED_YIELD #undef OF_HAVE_SOCKETS #undef OF_HAVE_STDNORETURN #undef OF_HAVE_SYMLINK #undef OF_HAVE_SYNC_BUILTINS #undef OF_HAVE_SYS_SOCKET_H #undef OF_HAVE_SYS_TYPES_H #undef OF_HAVE_SYS_UN_H #undef OF_HAVE_THREADS #undef OF_HAVE_UNICODE_TABLES #undef OF_HAVE_UNIX_SOCKETS #undef OF_HAVE__THREAD_LOCAL #undef OF_HAVE___THREAD #undef OF_NINTENDO_3DS #undef OF_NINTENDO_DS #undef OF_NO_SHARED #undef OF_OBJFW_RUNTIME #undef OF_UNIVERSAL #undef OF_WII |
Modified src/platform.h from [40ddf7ef54] to [927be68827].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
64 65 66 67 68 69 70 | #elif defined(__mips_eabi) && _MIPS_SZPTR == 32 # define OF_MIPS # define OF_MIPS_EABI #elif defined(__sparc64__) || (defined(__sparc__) && defined(__arch64__)) # define OF_SPARC64 #elif defined(__sparc__) && !defined(__arch64__) # define OF_SPARC | | > | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | #elif defined(__mips_eabi) && _MIPS_SZPTR == 32 # define OF_MIPS # define OF_MIPS_EABI #elif defined(__sparc64__) || (defined(__sparc__) && defined(__arch64__)) # define OF_SPARC64 #elif defined(__sparc__) && !defined(__arch64__) # define OF_SPARC #elif defined(__hppa64__) || defined(_PA_RISC2_0) # define OF_PA_RISC_2_0 #elif defined(__hppa__) || defined(_PA_RISC1_0) || defined(_PA_RISC1_1) # define OF_PA_RISC #elif defined(__ia64__) || defined(__IA64__) # define OF_ITANIUM #elif defined(__m68k__) # define OF_M68K # ifdef __mc68060__ # define OF_M68060 |
︙ | ︙ | |||
94 95 96 97 98 99 100 101 102 103 104 105 106 107 | # define OF_RISC_V_64 #elif defined(__riscv) # define OF_RISC_V #elif defined(__s390x__) # define OF_S390X #elif defined(__s390__) # define OF_S390 #endif #if defined(__APPLE__) # include <TargetConditionals.h> # if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \ (defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR) # define OF_IOS | > > | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | # define OF_RISC_V_64 #elif defined(__riscv) # define OF_RISC_V #elif defined(__s390x__) # define OF_S390X #elif defined(__s390__) # define OF_S390 #elif defined(__e2k__) # define OF_ELBRUS_2000 #endif #if defined(__APPLE__) # include <TargetConditionals.h> # if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \ (defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR) # define OF_IOS |
︙ | ︙ | |||
123 124 125 126 127 128 129 | #elif defined(__ANDROID__) # define OF_ANDROID #elif defined(__HAIKU__) # define OF_HAIKU #elif defined(_AIX) # define OF_AIX #elif defined(__MORPHOS__) | < | | < < < > > > > | 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | #elif defined(__ANDROID__) # define OF_ANDROID #elif defined(__HAIKU__) # define OF_HAIKU #elif defined(_AIX) # define OF_AIX #elif defined(__MORPHOS__) # define OF_MORPHOS # define OF_AMIGAOS #elif defined(__amigaos4__) # define OF_AMIGAOS4 # define OF_AMIGAOS #elif defined(__amigaos__) # define OF_AMIGAOS_M68K # define OF_AMIGAOS #elif defined(__sun__) # define OF_SOLARIS #elif defined(__QNX__) # define OF_QNX #elif defined(__hpux__) # define OF_HPUX #elif defined(_PSP) # define OF_PSP #elif defined(__DJGPP__) # define OF_DJGPP # define OF_MSDOS #elif defined(__riscos__) # define OF_ACORN_RISC_OS #elif defined(__MINT__) # define OF_MINT #endif #if defined(__ELF__) # define OF_ELF #elif defined(__MACH__) # define OF_MACH_O #endif #if defined(__PIC__) || defined(__pic__) # define OF_PIC #endif |
Renamed and modified src/platform/amiga/condition.m [022f3487c0] to src/platform/AmigaOS/OFPlainCondition.m [b17297ed32].
1 | /* | < < | | < > | | < > | | | < > | | | < > | | < > | | | | | < | < | | | | < | < | < > | | | < > | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFPlainCondition.h" #include <proto/exec.h> #include <devices/timer.h> #ifndef OF_AMIGAOS4 # include <clib/alib_protos.h> #endif int OFPlainConditionNew(OFPlainCondition *condition) { condition->waitingTasks = NULL; return 0; } int OFPlainConditionSignal(OFPlainCondition *condition) { Forbid(); @try { if (condition->waitingTasks == NULL) return 0; Signal(condition->waitingTasks->task, (1ul << condition->waitingTasks->sigBit)); condition->waitingTasks = condition->waitingTasks->next; } @finally { Permit(); } return 0; } int OFPlainConditionBroadcast(OFPlainCondition *condition) { Forbid(); @try { if (condition->waitingTasks == NULL) return 0; while (condition->waitingTasks != NULL) { Signal(condition->waitingTasks->task, (1ul << condition->waitingTasks->sigBit)); condition->waitingTasks = condition->waitingTasks->next; } } @finally { Permit(); } return 0; } int OFPlainConditionWait(OFPlainCondition *condition, OFPlainMutex *mutex) { ULONG signalMask = 0; return OFPlainConditionWaitOrExecSignal(condition, mutex, &signalMask); } int OFPlainConditionWaitOrExecSignal(OFPlainCondition *condition, OFPlainMutex *mutex, ULONG *signalMask) { struct OFPlainConditionWaitingTask waitingTask = { .task = FindTask(NULL), .sigBit = AllocSignal(-1) }; int error = 0; ULONG mask; if (waitingTask.sigBit == -1) return EAGAIN; Forbid(); if ((error = OFPlainMutexUnlock(mutex)) != 0) { FreeSignal(waitingTask.sigBit); return error; } waitingTask.next = condition->waitingTasks; condition->waitingTasks = &waitingTask; mask = Wait((1ul << waitingTask.sigBit) | *signalMask); if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask)) error = OFPlainMutexLock(mutex); else /* * This should not happen - it means something interrupted the * Wait(), so the best we can do is return EINTR. */ error = EINTR; FreeSignal(waitingTask.sigBit); Permit(); return error; } int OFPlainConditionTimedWait(OFPlainCondition *condition, OFPlainMutex *mutex, OFTimeInterval timeout) { ULONG signalMask = 0; return OFPlainConditionTimedWaitOrExecSignal(condition, mutex, timeout, &signalMask); } int OFPlainConditionTimedWaitOrExecSignal(OFPlainCondition *condition, OFPlainMutex *mutex, OFTimeInterval timeout, ULONG *signalMask) { struct OFPlainConditionWaitingTask waitingTask = { .task = FindTask(NULL), .sigBit = AllocSignal(-1) }; struct MsgPort port = { .mp_Node = { .ln_Type = NT_MSGPORT }, |
︙ | ︙ | |||
178 179 180 181 182 183 184 185 | #else .tr_time = { .tv_sec = (ULONG)timeout, .tv_micro = (timeout - request.tr_time.tv_sec) * 1000000 #endif } }; ULONG mask; | > < | | | | | < | | < | < < < < < < | < > | | < | < | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | #else .tr_time = { .tv_sec = (ULONG)timeout, .tv_micro = (timeout - request.tr_time.tv_sec) * 1000000 #endif } }; int error = 0; ULONG mask; NewList(&port.mp_MsgList); if (waitingTask.sigBit == -1 || port.mp_SigBit == -1) { error = EAGAIN; goto fail; } if (OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)&request, 0) != 0) { error = EAGAIN; goto fail; } Forbid(); if ((error = OFPlainMutexUnlock(mutex)) != 0) { Permit(); goto fail; } waitingTask.next = condition->waitingTasks; condition->waitingTasks = &waitingTask; SendIO((struct IORequest *)&request); mask = Wait((1ul << waitingTask.sigBit) | (1ul << port.mp_SigBit) | *signalMask); if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask)) error = OFPlainMutexLock(mutex); else if (mask & (1ul << port.mp_SigBit)) error = ETIMEDOUT; else /* * This should not happen - it means something interrupted the * Wait(), so the best we can do is return EINTR. */ error = EINTR; condition->waitingTasks = waitingTask.next; if (!CheckIO((struct IORequest *)&request)) { AbortIO((struct IORequest *)&request); WaitIO((struct IORequest *)&request); } CloseDevice((struct IORequest *)&request); Permit(); fail: if (waitingTask.sigBit != -1) FreeSignal(waitingTask.sigBit); if (port.mp_SigBit != -1) FreeSignal(port.mp_SigBit); return error; } int OFPlainConditionFree(OFPlainCondition *condition) { Forbid(); @try { if (condition->waitingTasks != NULL) return EBUSY; } @finally { Permit(); } return 0; } |
Renamed and modified src/platform/amiga/mutex.m [c8d24f47bf] to src/platform/AmigaOS/OFPlainMutex.m [635aa59c59].
1 | /* | < < | | < > | | < > | | < > | | < | | < | < > | | < > | | < > | | < > | | < > | | < > | | < > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFPlainMutex.h" #include <proto/exec.h> int OFPlainMutexNew(OFPlainMutex *mutex) { InitSemaphore(mutex); return 0; } int OFPlainMutexLock(OFPlainMutex *mutex) { ObtainSemaphore(mutex); return 0; } int OFPlainMutexTryLock(OFPlainMutex *mutex) { if (!AttemptSemaphore(mutex)) return EBUSY; return 0; } int OFPlainMutexUnlock(OFPlainMutex *mutex) { ReleaseSemaphore(mutex); return 0; } int OFPlainMutexFree(OFPlainMutex *mutex) { return 0; } int OFPlainRecursiveMutexNew(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexNew(rmutex); } int OFPlainRecursiveMutexLock(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexLock(rmutex); } int OFPlainRecursiveMutexTryLock(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexTryLock(rmutex); } int OFPlainRecursiveMutexUnlock(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexUnlock(rmutex); } int OFPlainRecursiveMutexFree(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexFree(rmutex); } |
Renamed and modified src/platform/amiga/thread.m [de7e15e20a] to src/platform/AmigaOS/OFPlainThread.m [70ea6c25e9].
1 | /* | < < | | < | | > | > | | | | | > | > < > | | < > | | | < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <assert.h> #include <errno.h> #import "OFPlainThread.h" #import "OFData.h" #import "OFTLSKey.h" #include <dos/dostags.h> #include <proto/dos.h> #include <proto/exec.h> #ifndef OF_MORPHOS extern void OFTLSKeyThreadExited(void); #endif static OFTLSKey threadKey; OF_CONSTRUCTOR() { OFEnsure(OFTLSKeyNew(&threadKey) == 0); } static void functionWrapper(void) { bool detached = false; OFPlainThread thread = (OFPlainThread)((struct Process *)FindTask(NULL))->pr_ExitData; OFEnsure(OFTLSKeySet(threadKey, thread) == 0); thread->function(thread->object); ObtainSemaphore(&thread->semaphore); @try { thread->done = true; #ifndef OF_MORPHOS OFTLSKeyThreadExited(); #endif if (thread->detached) detached = true; else if (thread->joinTask != NULL) Signal(thread->joinTask, (1ul << thread->joinSigBit)); } @finally { ReleaseSemaphore(&thread->semaphore); } if (detached) free(thread); } int OFPlainThreadAttributesInit(OFPlainThreadAttributes *attr) { attr->priority = 0; attr->stackSize = 0; return 0; } int OFPlainThreadNew(OFPlainThread *thread, const char *name, void (*function)(id), id object, const OFPlainThreadAttributes *attr) { OFMutableData *tags = nil; if ((*thread = calloc(1, sizeof(**thread))) == NULL) return ENOMEM; @try { (*thread)->function = function; (*thread)->object = object; InitSemaphore(&(*thread)->semaphore); tags = [[OFMutableData alloc] |
︙ | ︙ | |||
116 117 118 119 120 121 122 | ADD_TAG(NP_Output, ((struct Process *)FindTask(NULL))->pr_COS) ADD_TAG(NP_Error, ((struct Process *)FindTask(NULL))->pr_CES) ADD_TAG(NP_CloseInput, FALSE) ADD_TAG(NP_CloseOutput, FALSE) ADD_TAG(NP_CloseError, FALSE) if (attr != NULL && attr->priority != 0) { | | < | < | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | ADD_TAG(NP_Output, ((struct Process *)FindTask(NULL))->pr_COS) ADD_TAG(NP_Error, ((struct Process *)FindTask(NULL))->pr_CES) ADD_TAG(NP_CloseInput, FALSE) ADD_TAG(NP_CloseOutput, FALSE) ADD_TAG(NP_CloseError, FALSE) if (attr != NULL && attr->priority != 0) { if (attr->priority < 1 || attr->priority > 1) return EINVAL; /* * -1 should be -128 (lowest possible priority) while * +1 should be +127 (highest possible priority). */ ADD_TAG(NP_Priority, (attr->priority > 0 ? attr->priority * 127 : attr->priority * 128)) |
︙ | ︙ | |||
141 142 143 144 145 146 147 | ADD_TAG(TAG_DONE, 0) #undef ADD_TAG (*thread)->task = (struct Task *)CreateNewProc(tags.items); if ((*thread)->task == NULL) { free(*thread); | < | | | | | > > > > | > > | | < | | < | < | < | < > | | | | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | ADD_TAG(TAG_DONE, 0) #undef ADD_TAG (*thread)->task = (struct Task *)CreateNewProc(tags.items); if ((*thread)->task == NULL) { free(*thread); return EAGAIN; } } @catch (id e) { free(*thread); @throw e; } @finally { [tags release]; } return 0; } OFPlainThread OFCurrentPlainThread(void) { return OFTLSKeyGet(threadKey); } bool OFPlainThreadIsCurrent(OFPlainThread thread) { return (thread->task == FindTask(NULL)); } int OFPlainThreadJoin(OFPlainThread thread) { ObtainSemaphore(&thread->semaphore); if (thread->done) { ReleaseSemaphore(&thread->semaphore); free(thread); return 0; } @try { if (thread->detached || thread->joinTask != NULL) return EINVAL; if ((thread->joinSigBit = AllocSignal(-1)) == -1) return EAGAIN; thread->joinTask = FindTask(NULL); } @finally { ReleaseSemaphore(&thread->semaphore); } Wait(1ul << thread->joinSigBit); FreeSignal(thread->joinSigBit); assert(thread->done); free(thread); return 0; } int OFPlainThreadDetach(OFPlainThread thread) { ObtainSemaphore(&thread->semaphore); if (thread->done) free(thread); else thread->detached = true; ReleaseSemaphore(&thread->semaphore); return 0; } void OFSetThreadName(const char *name) { } |
Renamed and modified src/platform/amiga/OFString+PathAdditions.m [6f79ae7bc0] to src/platform/AmigaOS/OFString+PathAdditions.m [8907c31289].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
117 118 119 120 121 122 123 | { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." | | | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OFStringSearchBackwards].location; if (pos == OFNotFound || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringFromIndex: pos + 1]; [ret retain]; |
︙ | ︙ | |||
153 154 155 156 157 158 159 | } objc_autoreleasePoolPop(pool); return @""; } components = [components objectsInRange: | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | } objc_autoreleasePoolPop(pool); return @""; } components = [components objectsInRange: OFRangeMake(0, components.count - 1)]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } |
︙ | ︙ | |||
176 177 178 179 180 181 182 | return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." | | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OFStringSearchBackwards].location; if (pos == OFNotFound || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } fileName = [fileName substringToIndex: pos]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; |
︙ | ︙ | |||
233 234 235 236 237 238 239 | done = false; break; } if ([component isEqual: @"/"] && parent != nil && ![parent isEqual: @"/"]) { [array removeObjectsInRange: | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | done = false; break; } if ([component isEqual: @"/"] && parent != nil && ![parent isEqual: @"/"]) { [array removeObjectsInRange: OFRangeMake(i - 1, 2)]; done = false; break; } } } |
︙ | ︙ | |||
322 323 324 325 326 327 328 | count--; i--; continue; } if ([component isEqual: @".."]) | | < | 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | count--; i--; continue; } if ([component isEqual: @".."]) [components replaceObjectAtIndex: i withObject: @"/"]; } return [OFString pathWithComponents: components]; } - (OFString *)of_pathComponentToURLPathComponent { return self; } @end |
Renamed and modified src/platform/amiga/tlskey.m [c1bdeb2ced] to src/platform/AmigaOS/OFTLSKey.m [7115be10da].
1 | /* | < < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFTLSKey.h" #include <exec/semaphores.h> #include <proto/exec.h> /* * As we use this file in both the runtime and ObjFW, and since AmigaOS always * has the runtime, use the hashtable from the runtime. */ #import "runtime/private.h" static OFTLSKey firstKey = NULL, lastKey = NULL; static struct SignalSemaphore semaphore; static bool semaphoreInitialized = false; static uint32_t hashFunc(const void *ptr) { return (uint32_t)(uintptr_t)ptr; |
︙ | ︙ | |||
48 49 50 51 52 53 54 | { if (!semaphoreInitialized) { InitSemaphore(&semaphore); semaphoreInitialized = true; } } | < > | | | < > | | | < > | < < | | | < | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | { if (!semaphoreInitialized) { InitSemaphore(&semaphore); semaphoreInitialized = true; } } int OFTLSKeyNew(OFTLSKey *key) { if (!semaphoreInitialized) { /* * We might be called from another constructor, while ours has * not run yet. This is safe, as the constructor is definitely * run before a thread is spawned. */ InitSemaphore(&semaphore); semaphoreInitialized = true; } if ((*key = malloc(sizeof(**key))) == NULL) return ENOMEM; (*key)->table = NULL; ObtainSemaphore(&semaphore); @try { (*key)->next = NULL; (*key)->previous = lastKey; if (lastKey != NULL) lastKey->next = *key; lastKey = *key; if (firstKey == NULL) firstKey = *key; } @finally { ReleaseSemaphore(&semaphore); } /* We create the hash table lazily. */ return 0; } int OFTLSKeyFree(OFTLSKey key) { ObtainSemaphore(&semaphore); @try { if (key->previous != NULL) key->previous->next = key->next; if (key->next != NULL) key->next->previous = key->previous; if (firstKey == key) firstKey = key->next; if (lastKey == key) lastKey = key->previous; objc_hashtable_free(key->table); free(key); } @finally { ReleaseSemaphore(&semaphore); } return 0; } void * OFTLSKeyGet(OFTLSKey key) { void *ret; ObtainSemaphore(&semaphore); @try { if (key->table == NULL) return NULL; ret = objc_hashtable_get(key->table, FindTask(NULL)); } @finally { ReleaseSemaphore(&semaphore); } return ret; } int OFTLSKeySet(OFTLSKey key, void *ptr) { ObtainSemaphore(&semaphore); @try { struct Task *task = FindTask(NULL); if (key->table == NULL) key->table = objc_hashtable_new(hashFunc, equalFunc, 2); if (ptr == NULL) objc_hashtable_delete(key->table, task); else objc_hashtable_set(key->table, task, ptr); } @finally { ReleaseSemaphore(&semaphore); } return 0; } void OFTLSKeyThreadExited(void) { ObtainSemaphore(&semaphore); @try { struct Task *task = FindTask(NULL); for (OFTLSKey iter = firstKey; iter != NULL; iter = iter->next) if (iter->table != NULL) objc_hashtable_delete(iter->table, task); } @finally { ReleaseSemaphore(&semaphore); } } |
Renamed and modified src/atomic_builtins.h [249a6da122] to src/platform/GCC4.7/OFAtomic.h [3a2198950d].
1 | /* | < < | | | | | | | | | | | | | | | | | | > > > > > > > < < < < < < < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ static OF_INLINE int OFAtomicIntAdd(volatile int *_Nonnull p, int i) { return __atomic_add_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE int32_t OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i) { return __atomic_add_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE void *_Nullable OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i) { return __atomic_add_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE int OFAtomicIntSubtract(volatile int *_Nonnull p, int i) { return __atomic_sub_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE int32_t OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i) { return __atomic_sub_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE void *_Nullable OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i) { return __atomic_sub_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE int OFAtomicIntIncrease(volatile int *_Nonnull p) { return __atomic_add_fetch(p, 1, __ATOMIC_RELAXED); } static OF_INLINE int32_t OFAtomicInt32Increase(volatile int32_t *_Nonnull p) { return __atomic_add_fetch(p, 1, __ATOMIC_RELAXED); } static OF_INLINE int OFAtomicIntDecrease(volatile int *_Nonnull p) { return __atomic_sub_fetch(p, 1, __ATOMIC_RELAXED); } static OF_INLINE int32_t OFAtomicInt32Decrease(volatile int32_t *_Nonnull p) { return __atomic_sub_fetch(p, 1, __ATOMIC_RELAXED); } static OF_INLINE unsigned int OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i) { return __atomic_or_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE uint32_t OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i) { return __atomic_or_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE unsigned int OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i) { return __atomic_and_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE uint32_t OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i) { return __atomic_and_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE unsigned int OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i) { return __atomic_xor_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE uint32_t OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i) { return __atomic_xor_fetch(p, i, __ATOMIC_RELAXED); } static OF_INLINE bool OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n) { return __atomic_compare_exchange(p, &o, &n, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED); } static OF_INLINE bool OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n) { return __atomic_compare_exchange(p, &o, &n, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED); } static OF_INLINE bool OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p, void *_Nullable o, void *_Nullable n) { return __atomic_compare_exchange(p, &o, &n, false, __ATOMIC_RELAXED, __ATOMIC_RELAXED); } static OF_INLINE void OFMemoryBarrier(void) { __atomic_thread_fence(__ATOMIC_SEQ_CST); } static OF_INLINE void OFAcquireMemoryBarrier(void) { __atomic_thread_fence(__ATOMIC_ACQUIRE); } static OF_INLINE void OFReleaseMemoryBarrier(void) { __atomic_thread_fence(__ATOMIC_RELEASE); } |
Renamed and modified src/atomic_sync_builtins.h [9b099e15cf] to src/platform/GCC4/OFAtomic.h [46ae36c82b].
1 | /* | < < | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ static OF_INLINE int OFAtomicIntAdd(volatile int *_Nonnull p, int i) { return __sync_add_and_fetch(p, i); } static OF_INLINE int32_t OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i) { return __sync_add_and_fetch(p, i); } static OF_INLINE void *_Nullable OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i) { return __sync_add_and_fetch(p, (void *)i); } static OF_INLINE int OFAtomicIntSubtract(volatile int *_Nonnull p, int i) { return __sync_sub_and_fetch(p, i); } static OF_INLINE int32_t OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i) { return __sync_sub_and_fetch(p, i); } static OF_INLINE void *_Nullable OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i) { return __sync_sub_and_fetch(p, (void *)i); } static OF_INLINE int OFAtomicIntIncrease(volatile int *_Nonnull p) { return __sync_add_and_fetch(p, 1); } static OF_INLINE int32_t OFAtomicInt32Increase(volatile int32_t *_Nonnull p) { return __sync_add_and_fetch(p, 1); } static OF_INLINE int OFAtomicIntDecrease(volatile int *_Nonnull p) { return __sync_sub_and_fetch(p, 1); } static OF_INLINE int32_t OFAtomicInt32Decrease(volatile int32_t *_Nonnull p) { return __sync_sub_and_fetch(p, 1); } static OF_INLINE unsigned int OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i) { return __sync_or_and_fetch(p, i); } static OF_INLINE uint32_t OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i) { return __sync_or_and_fetch(p, i); } static OF_INLINE unsigned int OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i) { return __sync_and_and_fetch(p, i); } static OF_INLINE uint32_t OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i) { return __sync_and_and_fetch(p, i); } static OF_INLINE unsigned int OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i) { return __sync_xor_and_fetch(p, i); } static OF_INLINE uint32_t OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i) { return __sync_xor_and_fetch(p, i); } static OF_INLINE bool OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n) { return __sync_bool_compare_and_swap(p, o, n); } static OF_INLINE bool OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n) { return __sync_bool_compare_and_swap(p, o, n); } static OF_INLINE bool OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p, void *_Nullable o, void *_Nullable n) { return __sync_bool_compare_and_swap(p, o, n); } static OF_INLINE void OFMemoryBarrier(void) { __sync_synchronize(); } static OF_INLINE void OFAcquireMemoryBarrier(void) { __sync_synchronize(); } static OF_INLINE void OFReleaseMemoryBarrier(void) { __sync_synchronize(); } |
Added src/platform/MorphOS/OFTLSKey.m version [f46c8d88c6].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFTLSKey.h" int OFTLSKeyNew(OFTLSKey *key) { *key = TLSAllocA(NULL); if (*key == TLS_INVALID_INDEX) return EAGAIN; return 0; } int OFTLSKeyFree(OFTLSKey key) { return (TLSFree(key) ? 0 : EINVAL); } |
Renamed and modified src/platform/posix/condition.m [59d3a90643] to src/platform/POSIX/OFPlainCondition.m [d0abcf1839].
1 | /* | < < | | < > | | < > | | < > | | < > | | < > | | | < > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFPlainCondition.h" int OFPlainConditionNew(OFPlainCondition *condition) { return pthread_cond_init(condition, NULL); } int OFPlainConditionSignal(OFPlainCondition *condition) { return pthread_cond_signal(condition); } int OFPlainConditionBroadcast(OFPlainCondition *condition) { return pthread_cond_broadcast(condition); } int OFPlainConditionWait(OFPlainCondition *condition, OFPlainMutex *mutex) { return pthread_cond_wait(condition, mutex); } int OFPlainConditionTimedWait(OFPlainCondition *condition, OFPlainMutex *mutex, OFTimeInterval timeout) { struct timespec ts; ts.tv_sec = (time_t)timeout; ts.tv_nsec = (long)((timeout - ts.tv_sec) * 1000000000); return pthread_cond_timedwait(condition, mutex, &ts); } int OFPlainConditionFree(OFPlainCondition *condition) { return pthread_cond_destroy(condition); } |
Renamed and modified src/platform/posix/mutex.m [608d6df3a8] to src/platform/POSIX/OFPlainMutex.m [bcf658e6be].
1 | /* | < < | | < > | | < > | | < > | | < > | | < > | | < > | > | | | > | | | | | | < > | | < > | | < > | | < > | | < > | > > | | | | | < > | | > > | | | | | | | | | < > | | > > | | | | | | | | | < > | | > > | | | | | | | | < > | > > | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFPlainMutex.h" int OFPlainMutexNew(OFPlainMutex *mutex) { return pthread_mutex_init(mutex, NULL); } int OFPlainMutexLock(OFPlainMutex *mutex) { return pthread_mutex_lock(mutex); } int OFPlainMutexTryLock(OFPlainMutex *mutex) { return pthread_mutex_trylock(mutex); } int OFPlainMutexUnlock(OFPlainMutex *mutex) { return pthread_mutex_unlock(mutex); } int OFPlainMutexFree(OFPlainMutex *mutex) { return pthread_mutex_destroy(mutex); } #ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES int OFPlainRecursiveMutexNew(OFPlainRecursiveMutex *rmutex) { int error; pthread_mutexattr_t attr; if ((error = pthread_mutexattr_init(&attr)) != 0) return error; if ((error = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) != 0) return error; if ((error = pthread_mutex_init(rmutex, &attr)) != 0) return error; if ((error = pthread_mutexattr_destroy(&attr)) != 0) return error; return 0; } int OFPlainRecursiveMutexLock(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexLock(rmutex); } int OFPlainRecursiveMutexTryLock(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexTryLock(rmutex); } int OFPlainRecursiveMutexUnlock(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexUnlock(rmutex); } int OFPlainRecursiveMutexFree(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexFree(rmutex); } #else int OFPlainRecursiveMutexNew(OFPlainRecursiveMutex *rmutex) { int error; if ((error = OFPlainMutexNew(&rmutex->mutex)) != 0) return error; if ((error = OFTLSKeyNew(&rmutex->count)) != 0) return error; return 0; } int OFPlainRecursiveMutexLock(OFPlainRecursiveMutex *rmutex) { uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count); int error; if (count > 0) { if ((error = OFTLSKeySet(rmutex->count, (void *)(count + 1))) != 0) return error; return 0; } if ((error = OFPlainMutexLock(&rmutex->mutex)) != 0) return error; if ((error = OFTLSKeySet(rmutex->count, (void *)1)) != 0) { OFPlainMutexUnlock(&rmutex->mutex); return error; } return 0; } int OFPlainRecursiveMutexTryLock(OFPlainRecursiveMutex *rmutex) { uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count); int error; if (count > 0) { if ((error = OFTLSKeySet(rmutex->count, (void *)(count + 1))) != 0) return error; return 0; } if ((error = OFPlainMutexTryLock(&rmutex->mutex)) != 0) return error; if ((error = OFTLSKeySet(rmutex->count, (void *)1)) != 0) { OFPlainMutexUnlock(&rmutex->mutex); return error; } return 0; } int OFPlainRecursiveMutexUnlock(OFPlainRecursiveMutex *rmutex) { uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count); int error; if (count > 1) { if ((error = OFTLSKeySet(rmutex->count, (void *)(count - 1))) != 0) return error; return 0; } if ((error = OFTLSKeySet(rmutex->count, (void *)0)) != 0) return error; if ((error = OFPlainMutexUnlock(&rmutex->mutex)) != 0) return error; return 0; } int OFPlainRecursiveMutexFree(OFPlainRecursiveMutex *rmutex) { int error; if ((error = OFPlainMutexFree(&rmutex->mutex)) != 0) return error; if ((error = OFTLSKeyFree(rmutex->count)) != 0) return error; return 0; } #endif |
Renamed and modified src/platform/posix/thread.m [cdd7c510a1] to src/platform/POSIX/OFPlainThread.m [7bbb313eb6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | # include <pthread_np.h> #endif #ifdef OF_HAIKU # include <kernel/OS.h> #endif | | > | | | | | | | | < > | > | > > > | > | < | | > | | < | | < | < > | | < > | > | > > > | | > | | > > | < | | | | | | | | > > > > | > | > | | | | < | < | | > > | | < > | | < > | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | # include <pthread_np.h> #endif #ifdef OF_HAIKU # include <kernel/OS.h> #endif #import "OFPlainThread.h" #import "macros.h" static int minPrio = 0, maxPrio = 0, normalPrio = 0; struct ThreadContext { void (*function)(id object); id object; const char *name; }; /* * This is done here to make sure this is done as early as possible in the main * thread. */ OF_CONSTRUCTOR() { pthread_attr_t attr; if (pthread_attr_init(&attr) == 0) { #ifdef HAVE_PTHREAD_ATTR_GETSCHEDPOLICY int policy; #endif struct sched_param param; #ifdef HAVE_PTHREAD_ATTR_GETSCHEDPOLICY if (pthread_attr_getschedpolicy(&attr, &policy) == 0) { minPrio = sched_get_priority_min(policy); maxPrio = sched_get_priority_max(policy); if (minPrio == -1 || maxPrio == -1) minPrio = maxPrio = 0; } #endif if (pthread_attr_getschedparam(&attr, ¶m) != 0) normalPrio = param.sched_priority; else minPrio = maxPrio = 0; pthread_attr_destroy(&attr); } } static void * functionWrapper(void *data) { struct ThreadContext *ctx = data; if (ctx->name != NULL) OFSetThreadName(ctx->name); pthread_cleanup_push(free, data); ctx->function(ctx->object); pthread_cleanup_pop(1); return NULL; } int OFPlainThreadAttributesInit(OFPlainThreadAttributes *attr) { int error; pthread_attr_t POSIXAttr; attr->priority = 0; attr->stackSize = 0; if ((error = pthread_attr_init(&POSIXAttr)) != 0) { if (error == ENOSYS) return 0; return error; } error = pthread_attr_getstacksize(&POSIXAttr, &attr->stackSize); pthread_attr_destroy(&POSIXAttr); return error; } int OFPlainThreadNew(OFPlainThread *thread, const char *name, void (*function)(id), id object, const OFPlainThreadAttributes *attr) { int error = 0; pthread_attr_t POSIXAttr; bool POSIXAttrAvailable = true; if ((error = pthread_attr_init(&POSIXAttr)) != 0) { if (error == ENOSYS) POSIXAttrAvailable = false; else return error; } @try { struct ThreadContext *ctx; if (attr != NULL && POSIXAttrAvailable) { #ifndef OF_HPUX struct sched_param param; #endif if (attr->priority < -1 || attr->priority > 1) return EINVAL; #ifndef OF_HPUX # ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED if ((error = pthread_attr_setinheritsched(&POSIXAttr, PTHREAD_EXPLICIT_SCHED)) != 0) return error; # endif if ((error = pthread_attr_getschedparam(&POSIXAttr, ¶m)) != 0) return error; if (attr->priority < 0) { param.sched_priority = minPrio + (1.0f + attr->priority) * (normalPrio - minPrio); } else param.sched_priority = normalPrio + attr->priority * (maxPrio - normalPrio); if ((error = pthread_attr_setschedparam(&POSIXAttr, ¶m)) != 0) return error; #endif if (attr->stackSize > 0) { if ((error = pthread_attr_setstacksize( &POSIXAttr, attr->stackSize)) != 0) return error; } } if ((ctx = malloc(sizeof(*ctx))) == NULL) return ENOMEM; ctx->function = function; ctx->object = object; ctx->name = name; error = pthread_create(thread, (POSIXAttrAvailable ? &POSIXAttr : NULL), functionWrapper, ctx); } @finally { if (POSIXAttrAvailable) pthread_attr_destroy(&POSIXAttr); } return error; } int OFPlainThreadJoin(OFPlainThread thread) { void *ret; return pthread_join(thread, &ret); } int OFPlainThreadDetach(OFPlainThread thread) { return pthread_detach(thread); } void OFSetThreadName(const char *name) { #if defined(OF_HAIKU) rename_thread(find_thread(NULL), name); #elif defined(HAVE_PTHREAD_SET_NAME_NP) pthread_set_name_np(pthread_self(), name); #elif defined(HAVE_PTHREAD_SETNAME_NP) # if defined(OF_MACOS) || defined(OF_IOS) |
︙ | ︙ |
Renamed and modified src/platform/posix/OFProcess.m [a1d2451059] to src/platform/POSIX/OFSubprocess.m [f41e3bb02c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
27 28 29 30 31 32 33 | #endif #include "unistd_wrapper.h" #ifdef HAVE_SPAWN_H # include <spawn.h> #endif | | | | | | | | | | | | | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #endif #include "unistd_wrapper.h" #ifdef HAVE_SPAWN_H # include <spawn.h> #endif #import "OFSubprocess.h" #import "OFString.h" #import "OFArray.h" #import "OFDictionary.h" #import "OFLocale.h" #import "OFInitializationFailedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #ifndef HAVE_POSIX_SPAWNP extern char **environ; #endif @interface OFSubprocess () - (void)of_getArgv: (char ***)argv forProgramName: (OFString *)programName andArguments: (OFArray *)arguments; - (char **)of_environmentForDictionary: (OFDictionary *)dictionary; @end @implementation OFSubprocess + (instancetype)subprocessWithProgram: (OFString *)program { return [[[self alloc] initWithProgram: program] autorelease]; } + (instancetype)subprocessWithProgram: (OFString *)program arguments: (OFArray *)arguments { return [[[self alloc] initWithProgram: program arguments: arguments] autorelease]; } + (instancetype)subprocessWithProgram: (OFString *)program programName: (OFString *)programName arguments: (OFArray *)arguments { return [[[self alloc] initWithProgram: program programName: programName arguments: arguments] autorelease]; } + (instancetype)subprocessWithProgram: (OFString *)program programName: (OFString *)programName arguments: (OFArray *)arguments environment: (OFDictionary *)environment { return [[[self alloc] initWithProgram: program programName: programName arguments: arguments environment: environment] autorelease]; } |
︙ | ︙ | |||
125 126 127 128 129 130 131 | environment: (OFDictionary *)environment { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); const char *path; | | < | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | environment: (OFDictionary *)environment { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); const char *path; char **argv, **env = NULL; _pid = -1; _readPipe[0] = _writePipe[1] = -1; if (pipe(_readPipe) != 0 || pipe(_writePipe) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; path = [program cStringWithEncoding: [OFLocale encoding]]; [self of_getArgv: &argv forProgramName: programName andArguments: arguments]; @try { env = [self of_environmentForDictionary: environment]; #ifdef HAVE_POSIX_SPAWNP posix_spawn_file_actions_t actions; posix_spawnattr_t attr; if (posix_spawn_file_actions_init(&actions) != 0) @throw [OFInitializationFailedException exceptionWithClass: self.class]; |
︙ | ︙ | |||
202 203 204 205 206 207 208 209 210 | } if (_pid == -1) @throw [OFInitializationFailedException exceptionWithClass: self.class]; #endif } @finally { close(_readPipe[1]); close(_writePipe[0]); | > > | > > > > > > | 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | } if (_pid == -1) @throw [OFInitializationFailedException exceptionWithClass: self.class]; #endif } @finally { char **iter; close(_readPipe[1]); close(_writePipe[0]); OFFreeMemory(argv); if (env != NULL) for (iter = env; *iter != NULL; iter++) OFFreeMemory(*iter); OFFreeMemory(env); } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } |
︙ | ︙ | |||
230 231 232 233 234 235 236 | - (void)of_getArgv: (char ***)argv forProgramName: (OFString *)programName andArguments: (OFArray *)arguments { OFString *const *objects = arguments.objects; size_t i, count = arguments.count; | | | < < | | | < > | | | | | | | | | > | | > | | | | | | > > > > | > > | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | - (void)of_getArgv: (char ***)argv forProgramName: (OFString *)programName andArguments: (OFArray *)arguments { OFString *const *objects = arguments.objects; size_t i, count = arguments.count; OFStringEncoding encoding; *argv = OFAllocMemory(count + 2, sizeof(char *)); encoding = [OFLocale encoding]; (*argv)[0] = (char *)[programName cStringWithEncoding: encoding]; for (i = 0; i < count; i++) (*argv)[i + 1] = (char *)[objects[i] cStringWithEncoding: encoding]; (*argv)[i + 1] = NULL; } - (char **)of_environmentForDictionary: (OFDictionary *)environment { char **envp; size_t count; OFStringEncoding encoding; if (environment == nil) return NULL; encoding = [OFLocale encoding]; count = environment.count; envp = OFAllocZeroedMemory(count + 1, sizeof(char *)); @try { OFEnumerator *keyEnumerator = [environment keyEnumerator]; OFEnumerator *objectEnumerator = [environment objectEnumerator]; for (size_t i = 0; i < count; i++) { OFString *key; OFString *object; size_t keyLen, objectLen; key = [keyEnumerator nextObject]; object = [objectEnumerator nextObject]; keyLen = [key cStringLengthWithEncoding: encoding]; objectLen = [object cStringLengthWithEncoding: encoding]; envp[i] = OFAllocMemory(keyLen + objectLen + 2, 1); memcpy(envp[i], [key cStringWithEncoding: encoding], keyLen); envp[i][keyLen] = '='; memcpy(envp[i] + keyLen + 1, [object cStringWithEncoding: encoding], objectLen); envp[i][keyLen + objectLen + 1] = '\0'; } } @catch (id e) { for (size_t i = 0; i < count; i++) OFFreeMemory(envp[i]); OFFreeMemory(envp); @throw e; } return envp; } - (bool)lowlevelIsAtEndOfStream { if (_readPipe[0] == -1) |
︙ | ︙ | |||
317 318 319 320 321 322 323 | if (ret == 0) _atEndOfStream = true; return ret; } | | < | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | if (ret == 0) _atEndOfStream = true; return ret; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { ssize_t bytesWritten; if (_writePipe[1] == -1) @throw [OFNotOpenException exceptionWithObject: self]; if (length > SSIZE_MAX) |
︙ | ︙ |
Renamed and modified src/platform/posix/tlskey.m [01a5f7adde] to src/platform/POSIX/OFTLSKey.m [e854931fa2].
1 | /* | < < | | < > | | < > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFTLSKey.h" int OFTLSKeyNew(OFTLSKey *key) { return pthread_key_create(key, NULL); } int OFTLSKeyFree(OFTLSKey key) { return pthread_key_delete(key); } |
Renamed and modified src/atomic_powerpc.h [11a109fab0] to src/platform/PowerPC/OFAtomic.h [d8964b5a28].
1 | /* | < < | | | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ static OF_INLINE int OFAtomicIntAdd(volatile int *_Nonnull p, int i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "add %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return i; } static OF_INLINE int32_t OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "add %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return i; } static OF_INLINE void *_Nullable OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "add %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return (void *)i; } static OF_INLINE int OFAtomicIntSubtract(volatile int *_Nonnull p, int i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "sub %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return i; } static OF_INLINE int32_t OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "sub %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return i; } static OF_INLINE void *_Nullable OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "sub %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return (void *)i; } static OF_INLINE int OFAtomicIntIncrease(volatile int *_Nonnull p) { int i; __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %1\n\t" "addi %0, %0, 1\n\t" "stwcx. %0, 0, %1\n\t" "bne- 0b" : "=&r"(i) : "r"(p) : "cc", "memory" ); return i; } static OF_INLINE int32_t OFAtomicInt32Increase(volatile int32_t *_Nonnull p) { int32_t i; __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %1\n\t" "addi %0, %0, 1\n\t" "stwcx. %0, 0, %1\n\t" "bne- 0b" : "=&r"(i) : "r"(p) : "cc", "memory" ); return i; } static OF_INLINE int OFAtomicIntDecrease(volatile int *_Nonnull p) { int i; __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %1\n\t" "subi %0, %0, 1\n\t" "stwcx. %0, 0, %1\n\t" "bne- 0b" : "=&r"(i) : "r"(p) : "cc", "memory" ); return i; } static OF_INLINE int32_t OFAtomicInt32Decrease(volatile int32_t *_Nonnull p) { int32_t i; __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %1\n\t" "subi %0, %0, 1\n\t" "stwcx. %0, 0, %1\n\t" "bne- 0b" : "=&r"(i) : "r"(p) : "cc", "memory" ); return i; } static OF_INLINE unsigned int OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "or %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return i; } static OF_INLINE uint32_t OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "or %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return i; } static OF_INLINE unsigned int OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "and %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return i; } static OF_INLINE uint32_t OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "and %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return i; } static OF_INLINE unsigned int OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "xor %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return i; } static OF_INLINE uint32_t OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i) { __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %2\n\t" "xor %0, %0, %1\n\t" "stwcx. %0, 0, %2\n\t" "bne- 0b" : "=&r"(i) : "r"(i), "r"(p) : "cc", "memory" ); return i; } static OF_INLINE bool OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n) { int r; __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %3\n\t" "cmpw %0, %1\n\t" "bne 1f\n\t" "stwcx. %2, 0, %3\n\t" "bne- 0b\n\t" "li %0, 1\n\t" "b 2f\n\t" "1:\n\t" "stwcx. %0, 0, %3\n\t" "li %0, 0\n\t" "2:" : "=&r"(r) : "r"(o), "r"(n), "r"(p) : "cc", "memory" ); return r; } static OF_INLINE bool OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n) { int r; __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %3\n\t" "cmpw %0, %1\n\t" |
︙ | ︙ | |||
318 319 320 321 322 323 324 | : "cc", "memory" ); return r; } static OF_INLINE bool | < < < < < < < < < < < < < < < < < < < < < < < < < < | | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | : "cc", "memory" ); return r; } static OF_INLINE bool OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p, void *_Nullable o, void *_Nullable n) { int r; __asm__ __volatile__ ( "0:\n\t" "lwarx %0, 0, %3\n\t" |
︙ | ︙ | |||
371 372 373 374 375 376 377 | : "cc", "memory" ); return r; } static OF_INLINE void | | | | | 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 | : "cc", "memory" ); return r; } static OF_INLINE void OFMemoryBarrier(void) { __asm__ __volatile__ ( ".long 0x7C2004AC /* lwsync */" ::: "memory" ); } static OF_INLINE void OFAcquireMemoryBarrier(void) { __asm__ __volatile__ ( ".long 0x7C2004AC /* lwsync */" ::: "memory" ); } static OF_INLINE void OFReleaseMemoryBarrier(void) { __asm__ __volatile__ ( ".long 0x7C2004AC /* lwsync */" ::: "memory" ); } |
Renamed and modified src/platform/windows/condition.m [848a636ef0] to src/platform/Windows/OFPlainCondition.m [cd952f15d7].
1 | /* | < < | | < > | | < | | < | < > | < | | | < > | < | | | < > | > | | | | | < | | | < < | > > | > | | | | | < | < | | | < > | | < | | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFPlainCondition.h" #include <windows.h> int OFPlainConditionNew(OFPlainCondition *condition) { condition->count = 0; if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL) return EAGAIN; return 0; } int OFPlainConditionSignal(OFPlainCondition *condition) { if (!SetEvent(condition->event)) { switch (GetLastError()) { case ERROR_INVALID_HANDLE: return EINVAL; default: OFEnsure(0); } } return 0; } int OFPlainConditionBroadcast(OFPlainCondition *condition) { int count = condition->count; for (int i = 0; i < count; i++) { if (!SetEvent(condition->event)) { switch (GetLastError()) { case ERROR_INVALID_HANDLE: return EINVAL; default: OFEnsure(0); } } } return 0; } int OFPlainConditionWait(OFPlainCondition *condition, OFPlainMutex *mutex) { int error; DWORD status; if ((error = OFPlainMutexUnlock(mutex)) != 0) return error; OFAtomicIntIncrease(&condition->count); status = WaitForSingleObject(condition->event, INFINITE); OFAtomicIntDecrease(&condition->count); switch (status) { case WAIT_OBJECT_0: return OFPlainMutexLock(mutex); case WAIT_FAILED: switch (GetLastError()) { case ERROR_INVALID_HANDLE: return EINVAL; default: OFEnsure(0); } default: OFEnsure(0); } } int OFPlainConditionTimedWait(OFPlainCondition *condition, OFPlainMutex *mutex, OFTimeInterval timeout) { int error; DWORD status; if ((error = OFPlainMutexUnlock(mutex)) != 0) return error; OFAtomicIntIncrease(&condition->count); status = WaitForSingleObject(condition->event, timeout * 1000); OFAtomicIntDecrease(&condition->count); switch (status) { case WAIT_OBJECT_0: return OFPlainMutexLock(mutex); case WAIT_TIMEOUT: return ETIMEDOUT; case WAIT_FAILED: switch (GetLastError()) { case ERROR_INVALID_HANDLE: return EINVAL; default: OFEnsure(0); } default: OFEnsure(0); } } int OFPlainConditionFree(OFPlainCondition *condition) { if (condition->count != 0) return EBUSY; return (CloseHandle(condition->event) ? 0 : EINVAL); } |
Renamed and modified src/platform/windows/mutex.m [c67aeb237e] to src/platform/Windows/OFPlainMutex.m [f924adddc3].
1 | /* | < < | | < > | | < > | | < > | | < | | < | < > | | < > | | < > | | < > | | < > | | < > | | < > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFPlainMutex.h" #include <windows.h> int OFPlainMutexNew(OFPlainMutex *mutex) { InitializeCriticalSection(mutex); return 0; } int OFPlainMutexLock(OFPlainMutex *mutex) { EnterCriticalSection(mutex); return 0; } int OFPlainMutexTryLock(OFPlainMutex *mutex) { if (!TryEnterCriticalSection(mutex)) return EBUSY; return 0; } int OFPlainMutexUnlock(OFPlainMutex *mutex) { LeaveCriticalSection(mutex); return 0; } int OFPlainMutexFree(OFPlainMutex *mutex) { DeleteCriticalSection(mutex); return 0; } int OFPlainRecursiveMutexNew(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexNew(rmutex); } int OFPlainRecursiveMutexLock(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexLock(rmutex); } int OFPlainRecursiveMutexTryLock(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexTryLock(rmutex); } int OFPlainRecursiveMutexUnlock(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexUnlock(rmutex); } int OFPlainRecursiveMutexFree(OFPlainRecursiveMutex *rmutex) { return OFPlainMutexFree(rmutex); } |
Renamed and modified src/platform/windows/thread.m [d3d9eb9ec8] to src/platform/Windows/OFPlainThread.m [d2bc6a9806].
1 | /* | < < | | > | | < > | | < > | | | | < | < | < | < | | | | < | | | < > | | < | | | < > | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFPlainThread.h" #import "macros.h" #include <windows.h> struct ThreadContext { void (*function)(id); id object; }; static WINAPI void functionWrapper(struct ThreadContext *context) { context->function(context->object); free(context); } int OFPlainThreadAttributesInit(OFPlainThreadAttributes *attr) { attr->priority = 0; attr->stackSize = 0; return 0; } int OFPlainThreadNew(OFPlainThread *thread, const char *name, void (*function)(id), id object, const OFPlainThreadAttributes *attr) { DWORD priority = THREAD_PRIORITY_NORMAL; struct ThreadContext *context; DWORD threadID; if (attr != NULL && attr->priority != 0) { if (attr->priority < -1 || attr->priority > 1) return EINVAL; if (attr->priority < 0) priority = THREAD_PRIORITY_LOWEST + (1.0 + attr->priority) * (THREAD_PRIORITY_NORMAL - THREAD_PRIORITY_LOWEST); else priority = THREAD_PRIORITY_NORMAL + attr->priority * (THREAD_PRIORITY_HIGHEST - THREAD_PRIORITY_NORMAL); } if ((context = malloc(sizeof(*context))) == NULL) return ENOMEM; context->function = function; context->object = object; *thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0), (LPTHREAD_START_ROUTINE)functionWrapper, context, 0, &threadID); if (thread == NULL) { int error; switch (GetLastError()) { case ERROR_NOT_ENOUGH_MEMORY: error = ENOMEM; break; case ERROR_ACCESS_DENIED: error = EACCES; break; default: OFEnsure(0); } free(context); return error; } if (attr != NULL && attr->priority != 0) OFEnsure(!SetThreadPriority(*thread, priority)); return 0; } int OFPlainThreadJoin(OFPlainThread thread) { switch (WaitForSingleObject(thread, INFINITE)) { case WAIT_OBJECT_0: CloseHandle(thread); return 0; case WAIT_FAILED: switch (GetLastError()) { case ERROR_INVALID_HANDLE: return EINVAL; default: OFEnsure(0); } default: OFEnsure(0); } } int OFPlainThreadDetach(OFPlainThread thread) { CloseHandle(thread); return 0; } void OFSetThreadName(const char *name) { } |
Renamed and modified src/platform/windows/OFProcess.m [816ee6b0db] to src/platform/Windows/OFSubprocess.m [0ef8b1e769].
1 | /* | < < | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #include <string.h> #import "OFSubprocess.h" #import "OFArray.h" #import "OFData.h" #import "OFDictionary.h" #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFReadFailedException.h" #import "OFWriteFailedException.h" #include <windows.h> @interface OFSubprocess () - (OFChar16 *)of_wideEnvironmentForDictionary: (OFDictionary *)dictionary; - (char *)of_environmentForDictionary: (OFDictionary *)environment; @end @implementation OFSubprocess + (instancetype)subprocessWithProgram: (OFString *)program { return [[[self alloc] initWithProgram: program] autorelease]; } + (instancetype)subprocessWithProgram: (OFString *)program arguments: (OFArray *)arguments { return [[[self alloc] initWithProgram: program arguments: arguments] autorelease]; } + (instancetype)subprocessWithProgram: (OFString *)program programName: (OFString *)programName arguments: (OFArray *)arguments { return [[[self alloc] initWithProgram: program programName: programName arguments: arguments] autorelease]; } + (instancetype)subprocessWithProgram: (OFString *)program programName: (OFString *)programName arguments: (OFArray *)arguments environment: (OFDictionary *)environment { return [[[self alloc] initWithProgram: program programName: programName arguments: arguments environment: environment] autorelease]; } |
︙ | ︙ | |||
115 116 117 118 119 120 121 | @try { SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; void *pool; OFMutableString *argumentsString; | | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | @try { SECURITY_ATTRIBUTES sa; PROCESS_INFORMATION pi; void *pool; OFMutableString *argumentsString; _handle = INVALID_HANDLE_VALUE; _readPipe[0] = _writePipe[1] = NULL; sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; if (!CreatePipe(&_readPipe[0], &_readPipe[1], &sa, 0)) |
︙ | ︙ | |||
180 181 182 183 184 185 186 | if (containsSpaces) [argumentsString appendString: @"\""]; } if ([OFSystemInfo isWindowsNT]) { size_t length; | | | | < | | | | | | | | < | < | < | < | | < | < | < | < | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | if (containsSpaces) [argumentsString appendString: @"\""]; } if ([OFSystemInfo isWindowsNT]) { size_t length; OFChar16 *argumentsCopy; STARTUPINFOW si; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.hStdInput = _writePipe[0]; si.hStdOutput = _readPipe[1]; si.hStdError = GetStdHandle(STD_ERROR_HANDLE); si.dwFlags |= STARTF_USESTDHANDLES; length = argumentsString.UTF16StringLength; argumentsCopy = OFAllocMemory(length + 1, sizeof(OFChar16)); memcpy(argumentsCopy, argumentsString.UTF16String, (length + 1) * 2); @try { if (!CreateProcessW(program.UTF16String, argumentsCopy, NULL, NULL, TRUE, CREATE_UNICODE_ENVIRONMENT, [self of_wideEnvironmentForDictionary: environment], NULL, &si, &pi)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } @finally { OFFreeMemory(argumentsCopy); } } else { OFStringEncoding encoding = [OFLocale encoding]; STARTUPINFO si; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.hStdInput = _writePipe[0]; si.hStdOutput = _readPipe[1]; si.hStdError = GetStdHandle(STD_ERROR_HANDLE); si.dwFlags |= STARTF_USESTDHANDLES; if (!CreateProcessA([program cStringWithEncoding: encoding], (char *)[argumentsString cStringWithEncoding: encoding], NULL, NULL, TRUE, 0, [self of_environmentForDictionary: environment], NULL, &si, &pi)) @throw [OFInitializationFailedException exceptionWithClass: self.class]; } objc_autoreleasePoolPop(pool); _handle = pi.hProcess; CloseHandle(pi.hThread); CloseHandle(_readPipe[1]); CloseHandle(_writePipe[0]); } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_readPipe[0] != NULL) [self close]; [super dealloc]; } - (OFChar16 *)of_wideEnvironmentForDictionary: (OFDictionary *)environment { OFMutableData *env; OFEnumerator *keyEnumerator, *objectEnumerator; OFString *key, *object; const OFChar16 equal = '='; const OFChar16 zero[2] = { 0, 0 }; if (environment == nil) return NULL; env = [OFMutableData dataWithItemSize: sizeof(OFChar16)]; keyEnumerator = [environment keyEnumerator]; objectEnumerator = [environment objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { [env addItems: key.UTF16String count: key.UTF16StringLength]; [env addItems: &equal count: 1]; [env addItems: object.UTF16String count: object.UTF16StringLength]; [env addItems: &zero count: 1]; } [env addItems: zero count: 2]; return env.mutableItems; } - (char *)of_environmentForDictionary: (OFDictionary *)environment { OFStringEncoding encoding = [OFLocale encoding]; OFMutableData *env; OFEnumerator *keyEnumerator, *objectEnumerator; OFString *key, *object; if (environment == nil) return NULL; env = [OFMutableData data]; keyEnumerator = [environment keyEnumerator]; objectEnumerator = [environment objectEnumerator]; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) { [env addItems: [key cStringWithEncoding: encoding] count: [key cStringLengthWithEncoding: encoding]]; [env addItems: "=" count: 1]; [env addItems: [object cStringWithEncoding: encoding] count: [object cStringLengthWithEncoding: encoding]]; [env addItems: "" count: 1]; } [env addItems: "\0" count: 2]; return env.mutableItems; } - (bool)lowlevelIsAtEndOfStream { if (_readPipe[0] == NULL) @throw [OFNotOpenException exceptionWithObject: self]; return _atEndOfStream; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { DWORD ret; if (length > UINT32_MAX) @throw [OFOutOfRangeException exception]; if (_readPipe[0] == NULL) |
︙ | ︙ | |||
349 350 351 352 353 354 355 | if (ret == 0) _atEndOfStream = true; return ret; } | | < | | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | if (ret == 0) _atEndOfStream = true; return ret; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { DWORD bytesWritten; if (length > UINT32_MAX) @throw [OFOutOfRangeException exception]; if (_writePipe[1] == NULL) @throw [OFNotOpenException exceptionWithObject: self]; if (!WriteFile(_writePipe[1], buffer, (DWORD)length, &bytesWritten, NULL)) { int errNo = EIO; if (GetLastError() == ERROR_BROKEN_PIPE) errNo = EPIPE; @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: errNo]; } return (size_t)bytesWritten; } - (void)closeForWriting |
︙ | ︙ | |||
392 393 394 395 396 397 398 | { if (_readPipe[0] == NULL) @throw [OFNotOpenException exceptionWithObject: self]; [self closeForWriting]; CloseHandle(_readPipe[0]); | | | | | | | | | | | 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 | { if (_readPipe[0] == NULL) @throw [OFNotOpenException exceptionWithObject: self]; [self closeForWriting]; CloseHandle(_readPipe[0]); if (_handle != INVALID_HANDLE_VALUE) { TerminateProcess(_handle, 0); CloseHandle(_handle); } _handle = INVALID_HANDLE_VALUE; _readPipe[0] = NULL; [super close]; } - (int)waitForTermination { if (_readPipe[0] == NULL) @throw [OFNotOpenException exceptionWithObject: self]; if (_handle != INVALID_HANDLE_VALUE) { DWORD exitCode; WaitForSingleObject(_handle, INFINITE); if (GetExitCodeProcess(_handle, &exitCode)) _status = exitCode; else _status = GetLastError(); CloseHandle(_handle); _handle = INVALID_HANDLE_VALUE; } return _status; } @end |
Renamed and modified src/platform/windows/tlskey.m [c8aecc8bc3] to src/platform/Windows/OFTLSKey.m [819b78979d].
1 | /* | < < | | < > | | | > > > > | > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFTLSKey.h" int OFTLSKeyNew(OFTLSKey *key) { *key = TlsAlloc(); if (*key == TLS_OUT_OF_INDEXES) return EAGAIN; return 0; } int OFTLSKeyFree(OFTLSKey key) { return (TlsFree(key) ? 0 : EINVAL); } |
Modified src/platform/libfat/OFString+PathAdditions.m from [67bd48bd8c] to [9b9e52f706].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
151 152 153 154 155 156 157 | { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." | | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OFStringSearchBackwards].location; if (pos == OFNotFound || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringFromIndex: pos + 1]; [ret retain]; |
︙ | ︙ | |||
221 222 223 224 225 226 227 | return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." | | | | 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OFStringSearchBackwards].location; if (pos == OFNotFound || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } fileName = [fileName substringToIndex: pos]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; |
︙ | ︙ | |||
279 280 281 282 283 284 285 | done = false; break; } if ([component isEqual: @".."] && parent != nil && ![parent isEqual: @".."]) { [array removeObjectsInRange: | | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | done = false; break; } if ([component isEqual: @".."] && parent != nil && ![parent isEqual: @".."]) { [array removeObjectsInRange: OFRangeMake(i - 1, 2)]; done = false; break; } } } |
︙ | ︙ |
Renamed and modified src/atomic_osatomic.h [b2346ae318] to src/platform/macOS/OFAtomic.h [af25398c26].
1 | /* | < < | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include <libkern/OSAtomic.h> static OF_INLINE int OFAtomicIntAdd(volatile int *_Nonnull p, int i) { return OSAtomicAdd32(i, p); } static OF_INLINE int32_t OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i) { return OSAtomicAdd32(i, p); } static OF_INLINE void *_Nullable OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i) { #ifdef __LP64__ return (void *)OSAtomicAdd64(i, (int64_t *)p); #else return (void *)OSAtomicAdd32(i, (int32_t *)p); #endif } static OF_INLINE int OFAtomicIntSubtract(volatile int *_Nonnull p, int i) { return OSAtomicAdd32(-i, p); } static OF_INLINE int32_t OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i) { return OSAtomicAdd32(-i, p); } static OF_INLINE void *_Nullable OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i) { #ifdef __LP64__ return (void *)OSAtomicAdd64(-i, (int64_t *)p); #else return (void *)OSAtomicAdd32(-i, (int32_t *)p); #endif } static OF_INLINE int OFAtomicIntIncrease(volatile int *_Nonnull p) { return OSAtomicIncrement32(p); } static OF_INLINE int32_t OFAtomicInt32Increase(volatile int32_t *_Nonnull p) { return OSAtomicIncrement32(p); } static OF_INLINE int OFAtomicIntDecrease(volatile int *_Nonnull p) { return OSAtomicDecrement32(p); } static OF_INLINE int32_t OFAtomicInt32Decrease(volatile int32_t *_Nonnull p) { return OSAtomicDecrement32(p); } static OF_INLINE unsigned int OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i) { return OSAtomicOr32(i, p); } static OF_INLINE uint32_t OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i) { return OSAtomicOr32(i, p); } static OF_INLINE unsigned int OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i) { return OSAtomicAnd32(i, p); } static OF_INLINE uint32_t OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i) { return OSAtomicAnd32(i, p); } static OF_INLINE unsigned int OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i) { return OSAtomicXor32(i, p); } static OF_INLINE uint32_t OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i) { return OSAtomicXor32(i, p); } static OF_INLINE bool OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n) { return OSAtomicCompareAndSwapInt(o, n, p); } static OF_INLINE bool OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n) { return OSAtomicCompareAndSwap32(o, n, p); } static OF_INLINE bool OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p, void *_Nullable o, void *_Nullable n) { return OSAtomicCompareAndSwapPtr(o, n, p); } static OF_INLINE void OFMemoryBarrier(void) { OSMemoryBarrier(); } static OF_INLINE void OFAcquireMemoryBarrier(void) { OSMemoryBarrier(); } static OF_INLINE void OFReleaseMemoryBarrier(void) { OSMemoryBarrier(); } |
Modified src/platform/posix/OFString+PathAdditions.m from [b28e56e3b6] to [33c84f0ae4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
144 145 146 147 148 149 150 | { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OFStringSearchBackwards].location; if (pos == OFNotFound || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringFromIndex: pos + 1]; [ret retain]; |
︙ | ︙ | |||
213 214 215 216 217 218 219 | return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." | | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OFStringSearchBackwards].location; if (pos == OFNotFound || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } fileName = [fileName substringToIndex: pos]; [components replaceObjectAtIndex: [components count] - 1 withObject: fileName]; |
︙ | ︙ | |||
275 276 277 278 279 280 281 | done = false; break; } if ([component isEqual: @".."] && parent != nil && ![parent isEqual: @".."]) { [array removeObjectsInRange: | | | < | 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | done = false; break; } if ([component isEqual: @".."] && parent != nil && ![parent isEqual: @".."]) { [array removeObjectsInRange: OFRangeMake(i - 1, 2)]; done = false; break; } } } if (startsWithSlash) [array insertObject: @"" atIndex: 0]; if ([self hasSuffix: @"/"]) [array addObject: @""]; ret = [[array componentsJoinedByString: @"/"] retain]; objc_autoreleasePoolPop(pool); |
︙ | ︙ |
Modified src/platform/windows/OFString+PathAdditions.m from [3c2f48d580] to [3d18ffcbdd].
1 | /* | < < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ /* * This file is also used for MS-DOS and MiNT! Don't forget to #ifdef * Windows-specific parts! */ #include "config.h" #import "OFString+PathAdditions.h" #import "OFArray.h" #import "OFFileURLHandler.h" |
︙ | ︙ | |||
155 156 157 158 159 160 161 | { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." | | | | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | { void *pool = objc_autoreleasePoolPush(); OFString *ret, *fileName; size_t pos; fileName = self.lastPathComponent; pos = [fileName rangeOfString: @"." options: OFStringSearchBackwards].location; if (pos == OFNotFound || pos == 0) { objc_autoreleasePoolPop(pool); return @""; } ret = [fileName substringFromIndex: pos + 1]; [ret retain]; |
︙ | ︙ | |||
201 202 203 204 205 206 207 | } objc_autoreleasePoolPop(pool); return @"."; } components = [components objectsInRange: | | | 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | } objc_autoreleasePoolPop(pool); return @"."; } components = [components objectsInRange: OFRangeMake(0, components.count - 1)]; ret = [OFString pathWithComponents: components]; [ret retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } |
︙ | ︙ | |||
224 225 226 227 228 229 230 | return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." | | | | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | return [[self copy] autorelease]; pool = objc_autoreleasePoolPush(); components = [[self.pathComponents mutableCopy] autorelease]; fileName = components.lastObject; pos = [fileName rangeOfString: @"." options: OFStringSearchBackwards].location; if (pos == OFNotFound || pos == 0) { objc_autoreleasePoolPop(pool); return [[self copy] autorelease]; } fileName = [fileName substringToIndex: pos]; [components replaceObjectAtIndex: components.count - 1 withObject: fileName]; |
︙ | ︙ | |||
286 287 288 289 290 291 292 | if ([component isEqual: @".."] && parent != nil && ![parent isEqual: @".."] && ![parent hasSuffix: @":"] && ![parent hasSuffix: @":\\"] && ![parent hasSuffix: @"://"] && (![parent hasPrefix: @"\\"] || i != 1)) { [array removeObjectsInRange: | | | 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | if ([component isEqual: @".."] && parent != nil && ![parent isEqual: @".."] && ![parent hasSuffix: @":"] && ![parent hasSuffix: @":\\"] && ![parent hasSuffix: @"://"] && (![parent hasPrefix: @"\\"] || i != 1)) { [array removeObjectsInRange: OFRangeMake(i - 1, 2)]; done = false; break; } } } |
︙ | ︙ | |||
337 338 339 340 341 342 343 | if (components.count < 2) @throw [OFInvalidFormatException exception]; *URLEncodedHost = [[components objectAtIndex: 1] stringByURLEncodingWithAllowedCharacters: [OFCharacterSet URLHostAllowedCharacterSet]]; path = [OFString pathWithComponents: [components | | | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | if (components.count < 2) @throw [OFInvalidFormatException exception]; *URLEncodedHost = [[components objectAtIndex: 1] stringByURLEncodingWithAllowedCharacters: [OFCharacterSet URLHostAllowedCharacterSet]]; path = [OFString pathWithComponents: [components objectsInRange: OFRangeMake(2, components.count - 2)]]; } path = [path stringByReplacingOccurrencesOfString: @"\\" withString: @"/"]; path = [path stringByPrependingString: @"/"]; return path; |
︙ | ︙ |
Renamed and modified src/atomic_x86.h [61a2fa833b] to src/platform/x86/OFAtomic.h [db489edc3a].
1 | /* | < < | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ OF_ASSUME_NONNULL_BEGIN static OF_INLINE int OFAtomicIntAdd(volatile int *_Nonnull p, int i) { if (sizeof(int) == 4) __asm__ __volatile__ ( "lock\n\t" "xaddl %0, %2\n\t" "addl %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); #ifdef OF_X86_64 else if (sizeof(int) == 8) __asm__ __volatile__ ( "lock\n\t" "xaddq %0, %2\n\t" "addq %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); #endif else abort(); return i; } static OF_INLINE int32_t OFAtomicInt32Add(volatile int32_t *_Nonnull p, int32_t i) { __asm__ __volatile__ ( "lock\n\t" "xaddl %0, %2\n\t" "addl %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); return i; } static OF_INLINE void *_Nullable OFAtomicPointerAdd(void *volatile _Nullable *_Nonnull p, intptr_t i) { #if defined(OF_X86_64) __asm__ __volatile__ ( "lock\n\t" "xaddq %0, %2\n\t" "addq %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); return (void *)i; #elif defined(OF_X86) __asm__ __volatile__ ( "lock\n\t" "xaddl %0, %2\n\t" "addl %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); return (void *)i; #endif } static OF_INLINE int OFAtomicIntSubtract(volatile int *_Nonnull p, int i) { if (sizeof(int) == 4) __asm__ __volatile__ ( "negl %0\n\t" "lock\n\t" "xaddl %0, %2\n\t" "subl %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); #ifdef OF_X86_64 else if (sizeof(int) == 8) __asm__ __volatile__ ( "negq %0\n\t" "lock\n\t" "xaddq %0, %2\n\t" "subq %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); #endif else abort(); return i; } static OF_INLINE int32_t OFAtomicInt32Subtract(volatile int32_t *_Nonnull p, int32_t i) { __asm__ __volatile__ ( "negl %0\n\t" "lock\n\t" "xaddl %0, %2\n\t" "subl %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); return i; } static OF_INLINE void *_Nullable OFAtomicPointerSubtract(void *volatile _Nullable *_Nonnull p, intptr_t i) { #if defined(OF_X86_64) __asm__ __volatile__ ( "negq %0\n\t" "lock\n\t" "xaddq %0, %2\n\t" "subq %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); return (void *)i; #elif defined(OF_X86) __asm__ __volatile__ ( "negl %0\n\t" "lock\n\t" "xaddl %0, %2\n\t" "subl %1, %0" : "+&r"(i) : "r"(i), "m"(*p) ); return (void *)i; #endif } static OF_INLINE int OFAtomicIntIncrease(volatile int *_Nonnull p) { int i; if (sizeof(int) == 4) __asm__ __volatile__ ( "xorl %0, %0\n\t" "incl %0\n\t" "lock\n\t" "xaddl %0, %1\n\t" "incl %0" : "=&r"(i) : "m"(*p) ); #ifdef OF_X86_64 else if (sizeof(int) == 8) __asm__ __volatile__ ( "xorq %0, %0\n\t" "incq %0\n\t" "lock\n\t" "xaddq %0, %1\n\t" "incq %0" : "=&r"(i) : "m"(*p) ); #endif else abort(); return i; } static OF_INLINE int32_t OFAtomicInt32Increase(volatile int32_t *_Nonnull p) { int32_t i; __asm__ __volatile__ ( "xorl %0, %0\n\t" "incl %0\n\t" "lock\n\t" "xaddl %0, %1\n\t" "incl %0" : "=&r"(i) : "m"(*p) ); return i; } static OF_INLINE int OFAtomicIntDecrease(volatile int *_Nonnull p) { int i; if (sizeof(int) == 4) __asm__ __volatile__ ( "xorl %0, %0\n\t" "decl %0\n\t" "lock\n\t" "xaddl %0, %1\n\t" "decl %0" : "=&r"(i) : "m"(*p) ); #ifdef OF_X86_64 else if (sizeof(int) == 8) __asm__ __volatile__ ( "xorq %0, %0\n\t" "decq %0\n\t" "lock\n\t" "xaddq %0, %1\n\t" "decq %0" : "=&r"(i) : "m"(*p) ); #endif else abort(); return i; } static OF_INLINE int32_t OFAtomicInt32Decrease(volatile int32_t *_Nonnull p) { int32_t i; __asm__ __volatile__ ( "xorl %0, %0\n\t" "decl %0\n\t" "lock\n\t" "xaddl %0, %1\n\t" "decl %0" : "=&r"(i) : "m"(*p) ); return i; } static OF_INLINE unsigned int OFAtomicIntOr(volatile unsigned int *_Nonnull p, unsigned int i) { if (sizeof(int) == 4) __asm__ __volatile__ ( "0:\n\t" "movl %2, %0\n\t" "movl %0, %%eax\n\t" "orl %1, %0\n\t" "lock\n\t" "cmpxchg %0, %2\n\t" "jne 0b" : "=&r"(i) : "r"(i), "m"(*p) : "eax", "cc" ); #ifdef OF_X86_64 else if (sizeof(int) == 8) __asm__ __volatile__ ( "0:\n\t" "movq %2, %0\n\t" "movq %0, %%rax\n\t" "orq %1, %0\n\t" "lock\n\t" |
︙ | ︙ | |||
292 293 294 295 296 297 298 | else abort(); return i; } static OF_INLINE uint32_t | | | | | 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | else abort(); return i; } static OF_INLINE uint32_t OFAtomicInt32Or(volatile uint32_t *_Nonnull p, uint32_t i) { __asm__ __volatile__ ( "0:\n\t" "movl %2, %0\n\t" "movl %0, %%eax\n\t" "orl %1, %0\n\t" "lock\n\t" "cmpxchg %0, %2\n\t" "jne 0b" : "=&r"(i) : "r"(i), "m"(*p) : "eax", "cc" ); return i; } static OF_INLINE unsigned int OFAtomicIntAnd(volatile unsigned int *_Nonnull p, unsigned int i) { if (sizeof(int) == 4) __asm__ __volatile__ ( "0:\n\t" "movl %2, %0\n\t" "movl %0, %%eax\n\t" "andl %1, %0\n\t" "lock\n\t" "cmpxchg %0, %2\n\t" "jne 0b" : "=&r"(i) : "r"(i), "m"(*p) : "eax", "cc" ); #ifdef OF_X86_64 else if (sizeof(int) == 8) __asm__ __volatile__ ( "0:\n\t" "movq %2, %0\n\t" "movq %0, %%rax\n\t" "andq %1, %0\n\t" "lock\n\t" |
︙ | ︙ | |||
348 349 350 351 352 353 354 | else abort(); return i; } static OF_INLINE uint32_t | | | | | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | else abort(); return i; } static OF_INLINE uint32_t OFAtomicInt32And(volatile uint32_t *_Nonnull p, uint32_t i) { __asm__ __volatile__ ( "0:\n\t" "movl %2, %0\n\t" "movl %0, %%eax\n\t" "andl %1, %0\n\t" "lock\n\t" "cmpxchg %0, %2\n\t" "jne 0b" : "=&r"(i) : "r"(i), "m"(*p) : "eax", "cc" ); return i; } static OF_INLINE unsigned int OFAtomicIntXor(volatile unsigned int *_Nonnull p, unsigned int i) { if (sizeof(int) == 4) __asm__ __volatile__ ( "0:\n\t" "movl %2, %0\n\t" "movl %0, %%eax\n\t" "xorl %1, %0\n\t" "lock\n\t" "cmpxchg %0, %2\n\t" "jne 0b" : "=&r"(i) : "r"(i), "m"(*p) : "eax", "cc" ); #ifdef OF_X86_64 else if (sizeof(int) == 8) __asm__ __volatile__ ( "0:\n\t" "movq %2, %0\n\t" "movq %0, %%rax\n\t" "xorq %1, %0\n\t" "lock\n\t" |
︙ | ︙ | |||
404 405 406 407 408 409 410 | else abort(); return i; } static OF_INLINE uint32_t | | | | | | | | | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | else abort(); return i; } static OF_INLINE uint32_t OFAtomicInt32Xor(volatile uint32_t *_Nonnull p, uint32_t i) { __asm__ __volatile__ ( "0:\n\t" "movl %2, %0\n\t" "movl %0, %%eax\n\t" "xorl %1, %0\n\t" "lock\n\t" "cmpxchgl %0, %2\n\t" "jne 0b" : "=&r"(i) : "r"(i), "m"(*p) : "eax", "cc" ); return i; } static OF_INLINE bool OFAtomicIntCompareAndSwap(volatile int *_Nonnull p, int o, int n) { int r; __asm__ __volatile__ ( "lock\n\t" "cmpxchg %2, %3\n\t" "sete %b0\n\t" "movzbl %b0, %0" : "=&d"(r), "+a"(o) /* use d instead of r to avoid a gcc bug */ : "r"(n), "m"(*p) : "cc" ); return r; } static OF_INLINE bool OFAtomicInt32CompareAndSwap(volatile int32_t *_Nonnull p, int32_t o, int32_t n) { int r; __asm__ __volatile__ ( "lock\n\t" "cmpxchg %2, %3\n\t" "sete %b0\n\t" "movzbl %b0, %0" : "=&d"(r), "+a"(o) /* use d instead of r to avoid a gcc bug */ : "r"(n), "m"(*p) : "cc" ); return r; } static OF_INLINE bool OFAtomicPointerCompareAndSwap(void *volatile _Nullable *_Nonnull p, void *_Nullable o, void *_Nullable n) { int r; __asm__ __volatile__ ( "lock\n\t" "cmpxchg %2, %3\n\t" "sete %b0\n\t" "movzbl %b0, %0" : "=&d"(r), "+a"(o) /* use d instead of r to avoid a gcc bug */ : "r"(n), "m"(*p) : "cc" ); return r; } static OF_INLINE void OFMemoryBarrier(void) { __asm__ __volatile__ ( "mfence" ::: "memory" ); } static OF_INLINE void OFAcquireMemoryBarrier(void) { __asm__ __volatile__ ("" ::: "memory"); } static OF_INLINE void OFReleaseMemoryBarrier(void) { __asm__ __volatile__ ("" ::: "memory"); } OF_ASSUME_NONNULL_END |
Modified src/runtime/Makefile from [0941bab434] to [6dd30f7bce].
1 2 3 4 | include ../../extra.mk SUBDIRS = lookup-asm SUBDIRS_AFTER = ${LINKLIB} | < | 1 2 3 4 5 6 7 8 9 10 11 | include ../../extra.mk SUBDIRS = lookup-asm SUBDIRS_AFTER = ${LINKLIB} DISTCLEAN = Info.plist SHARED_LIB = ${OBJFWRT_SHARED_LIB} STATIC_LIB = ${OBJFWRT_STATIC_LIB} FRAMEWORK = ${OBJFWRT_FRAMEWORK} AMIGA_LIB = ${OBJFWRT_AMIGA_LIB} LIB_MAJOR = ${OBJFWRT_LIB_MAJOR} |
︙ | ︙ | |||
29 30 31 32 33 34 35 | protocol.m \ selector.m \ sparsearray.m \ static-instances.m \ synchronized.m \ tagged-pointer.m \ ${USE_SRCS_THREADS} | | | | | | | | < < < < < < < < > | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | protocol.m \ selector.m \ sparsearray.m \ static-instances.m \ synchronized.m \ tagged-pointer.m \ ${USE_SRCS_THREADS} SRCS_THREADS = OFOnce.m \ OFPlainMutex.m \ OFTLSKey.m \ threading.m INCLUDES = ObjFWRT.h includesubdir = ObjFWRT OBJS_EXTRA = lookup-asm/lookup-asm.a LIB_OBJS_EXTRA = lookup-asm/lookup-asm.lib.a AMIGA_LIB_OBJS_START = amiga-library.amigalib.o AMIGA_LIB_OBJS_EXTRA = amiga-glue.amigalib.o \ lookup-asm/lookup-asm.amigalib.a \ amiga-end.amigalib.o include ../../buildsys.mk CPPFLAGS += -I. -I.. -I../.. \ -DOBJC_COMPILING_RUNTIME \ -DOBJFWRT_AMIGA_LIB=\"${OBJFWRT_AMIGA_LIB}\" \ -DOBJFWRT_LIB_MAJOR=${OBJFWRT_LIB_MAJOR} \ -DOBJFWRT_LIB_MINOR=${OBJFWRT_LIB_MINOR} AMIGA_LIB_CFLAGS += -DOBJC_COMPILING_AMIGA_LIBRARY LD = ${OBJC} FRAMEWORK_LIBS = ${LIBS} |
Added src/runtime/OFOnce.m version [9cc54fa246].
> > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "ObjFWRT.h" #import "private.h" #include "../OFOnce.m" |
Added src/runtime/OFPlainMutex.m version [1b4abcc3c8].
> > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "ObjFWRT.h" #import "private.h" #include "../OFPlainMutex.m" |
Added src/runtime/OFTLSKey.m version [c512b1fdd8].
> > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "ObjFWRT.h" #import "private.h" #include "../OFTLSKey.m" |
Modified src/runtime/ObjFWRT.h from [1dfaeda4bc] to [87156bda73].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
144 145 146 147 148 149 150 | typedef id _Nullable (*IMP)(id _Nonnull object, SEL _Nonnull selector, ...); /** * @brief A handler for uncaught exceptions. * * @param exception The exception which was not caught. */ | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | typedef id _Nullable (*IMP)(id _Nonnull object, SEL _Nonnull selector, ...); /** * @brief A handler for uncaught exceptions. * * @param exception The exception which was not caught. */ typedef void (*objc_uncaught_exception_handler)(id _Nullable exception); /** * @brief A handler for mutation during enumeration. * * @param object The object that was mutated during enumeration */ typedef void (*objc_enumeration_mutation_handler)(id _Nonnull object); /** * @brief A struct representing a call to super. */ struct objc_super { /** * @brief The object on which to perform the super call. |
︙ | ︙ | |||
518 519 520 521 522 523 524 | * @return A copy of the attribute value. You need to call `free()` on it when * done. */ extern char *_Nullable property_copyAttributeValue( objc_property_t _Nonnull property, const char *_Nonnull name); /** | | | | | | | | 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | * @return A copy of the attribute value. You need to call `free()` on it when * done. */ extern char *_Nullable property_copyAttributeValue( objc_property_t _Nonnull property, const char *_Nonnull name); /** * @brief Deinitializes the Objective-C runtime. * * This frees all data structures used by the runtime, after which Objective-C * can no longer be used inside the current process. This is only useful for * debugging and tests. */ extern void objc_deinit(void); /** * @brief Sets the handler for uncaught exceptions. * * @param handler The new handler for uncaught exceptions * @return The old handler for uncaught exceptions */ extern _Nullable objc_uncaught_exception_handler objc_setUncaughtExceptionHandler( objc_uncaught_exception_handler _Nullable handler); /** * @brief Sets the forwarding handler for unimplemented methods. * * @param forward The forwarding handler for regular methods * @param stretForward The forwarding handler for methods using the struct * return ABI */ extern void objc_setForwardHandler(IMP _Nullable forward, IMP _Nullable stretForward); /** * @brief Sets the handler for mutations during enumeration. * * @param handler The handler for mutations during enumeration */ extern void objc_setEnumerationMutationHandler( objc_enumeration_mutation_handler _Nullable handler); /** * @brief Constructs an instance of the specified class in the specified array * of bytes. * * @param class_ The class of which to construct an instance * @param bytes An array of bytes of at least the length of the instance size. |
︙ | ︙ |
Modified src/runtime/amiga-end.m from [0d112ca98e] to [1fee00da70].
1 | /* | < < | > > | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "platform.h" #ifdef OF_MORPHOS __asm__ ( ".section .eh_frame, \"aw\"\n" " .long 0\n" ".section .ctors, \"aw\"\n" " .long 0" ); #else __asm__ ( "" ); #endif |
Added src/runtime/amiga-funcarray.inc version [820bef97bb].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ /* This file is automatically generated from amiga-library.xml */ (CONST_APTR)glue_objc_init, (CONST_APTR)glue___objc_exec_class, (CONST_APTR)glue_objc_msg_lookup, (CONST_APTR)glue_objc_msg_lookup_stret, (CONST_APTR)glue_objc_msg_lookup_super, (CONST_APTR)glue_objc_msg_lookup_super_stret, (CONST_APTR)glue_objc_lookUpClass, (CONST_APTR)glue_objc_getClass, (CONST_APTR)glue_objc_getRequiredClass, (CONST_APTR)glue_objc_lookup_class, (CONST_APTR)glue_objc_get_class, (CONST_APTR)glue_objc_exception_throw, (CONST_APTR)glue_objc_sync_enter, (CONST_APTR)glue_objc_sync_exit, (CONST_APTR)glue_objc_getProperty, (CONST_APTR)glue_objc_setProperty, (CONST_APTR)glue_objc_getPropertyStruct, (CONST_APTR)glue_objc_setPropertyStruct, (CONST_APTR)glue_objc_enumerationMutation, (CONST_APTR)glue___gnu_objc_personality, (CONST_APTR)glue_objc_retain, (CONST_APTR)glue_objc_retainBlock, (CONST_APTR)glue_objc_retainAutorelease, (CONST_APTR)glue_objc_release, (CONST_APTR)glue_objc_autorelease, (CONST_APTR)glue_objc_autoreleaseReturnValue, (CONST_APTR)glue_objc_retainAutoreleaseReturnValue, (CONST_APTR)glue_objc_retainAutoreleasedReturnValue, (CONST_APTR)glue_objc_storeStrong, (CONST_APTR)glue_objc_storeWeak, (CONST_APTR)glue_objc_loadWeakRetained, (CONST_APTR)glue_objc_initWeak, (CONST_APTR)glue_objc_destroyWeak, (CONST_APTR)glue_objc_loadWeak, (CONST_APTR)glue_objc_copyWeak, (CONST_APTR)glue_objc_moveWeak, (CONST_APTR)glue_sel_registerName, (CONST_APTR)glue_sel_getName, (CONST_APTR)glue_sel_isEqual, (CONST_APTR)glue_objc_allocateClassPair, (CONST_APTR)glue_objc_registerClassPair, (CONST_APTR)glue_objc_getClassList, (CONST_APTR)glue_objc_copyClassList, (CONST_APTR)glue_class_isMetaClass, (CONST_APTR)glue_class_getName, (CONST_APTR)glue_class_getSuperclass, (CONST_APTR)glue_class_getInstanceSize, (CONST_APTR)glue_class_respondsToSelector, (CONST_APTR)glue_class_conformsToProtocol, (CONST_APTR)glue_class_getMethodImplementation, (CONST_APTR)glue_class_getMethodImplementation_stret, (CONST_APTR)glue_class_getInstanceMethod, (CONST_APTR)glue_class_addMethod, (CONST_APTR)glue_class_replaceMethod, (CONST_APTR)glue_object_getClass, (CONST_APTR)glue_object_setClass, (CONST_APTR)glue_object_getClassName, (CONST_APTR)glue_protocol_getName, (CONST_APTR)glue_protocol_isEqual, (CONST_APTR)glue_protocol_conformsToProtocol, (CONST_APTR)glue_objc_setUncaughtExceptionHandler, (CONST_APTR)glue_objc_setForwardHandler, (CONST_APTR)glue_objc_setEnumerationMutationHandler, (CONST_APTR)glue_objc_constructInstance, (CONST_APTR)glue_objc_deinit, (CONST_APTR)glue_class_copyIvarList, (CONST_APTR)glue_ivar_getName, (CONST_APTR)glue_ivar_getTypeEncoding, (CONST_APTR)glue_ivar_getOffset, (CONST_APTR)glue_class_copyMethodList, (CONST_APTR)glue_method_getName, (CONST_APTR)glue_method_getTypeEncoding, (CONST_APTR)glue_class_copyPropertyList, (CONST_APTR)glue_property_getName, (CONST_APTR)glue_property_copyAttributeValue, (CONST_APTR)glue_objc_destructInstance, (CONST_APTR)glue_objc_autoreleasePoolPush, (CONST_APTR)glue_objc_autoreleasePoolPop, (CONST_APTR)glue__objc_rootAutorelease, (CONST_APTR)glue_objc_hashtable_new, (CONST_APTR)glue_objc_hashtable_set, (CONST_APTR)glue_objc_hashtable_get, (CONST_APTR)glue_objc_hashtable_delete, (CONST_APTR)glue_objc_hashtable_free, (CONST_APTR)glue_objc_setTaggedPointerSecret, (CONST_APTR)glue_objc_registerTaggedPointerClass, (CONST_APTR)glue_object_isTaggedPointer, (CONST_APTR)glue_object_getTaggedPointerValue, (CONST_APTR)glue_objc_createTaggedPointer, |
Added src/runtime/amiga-glue.h version [dc66f09f8a].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ /* This file is automatically generated from amiga-library.xml */ #import "ObjFWRT.h" #import "private.h" #ifdef OF_AMIGAOS_M68K # define PPC_PARAMS(...) (void) # define M68K_ARG(type, name, reg) \ register type reg##name __asm__(#reg); \ type name = reg##name; #else # define PPC_PARAMS(...) (__VA_ARGS__) # define M68K_ARG(...) #endif extern bool glue_objc_init PPC_PARAMS(unsigned int version, struct objc_libc *libc); extern void glue___objc_exec_class PPC_PARAMS(struct objc_module *_Nonnull module); extern IMP _Nonnull glue_objc_msg_lookup PPC_PARAMS(id _Nullable object, SEL _Nonnull selector); extern IMP _Nonnull glue_objc_msg_lookup_stret PPC_PARAMS(id _Nullable object, SEL _Nonnull selector); extern IMP _Nonnull glue_objc_msg_lookup_super PPC_PARAMS(struct objc_super *_Nonnull super, SEL _Nonnull selector); extern IMP _Nonnull glue_objc_msg_lookup_super_stret PPC_PARAMS(struct objc_super *_Nonnull super, SEL _Nonnull selector); extern Class _Nullable glue_objc_lookUpClass PPC_PARAMS(const char *_Nonnull name); extern Class _Nullable glue_objc_getClass PPC_PARAMS(const char *_Nonnull name); extern Class _Nonnull glue_objc_getRequiredClass PPC_PARAMS(const char *_Nonnull name); extern Class _Nullable glue_objc_lookup_class PPC_PARAMS(const char *_Nonnull name); extern Class _Nonnull glue_objc_get_class PPC_PARAMS(const char *_Nonnull name); extern void glue_objc_exception_throw PPC_PARAMS(id _Nonnull object); extern int glue_objc_sync_enter PPC_PARAMS(id _Nullable object); extern int glue_objc_sync_exit PPC_PARAMS(id _Nullable object); extern id _Nullable glue_objc_getProperty PPC_PARAMS(id _Nonnull self, SEL _Nonnull _cmd, ptrdiff_t offset, bool atomic); extern void glue_objc_setProperty PPC_PARAMS(id _Nonnull self, SEL _Nonnull _cmd, ptrdiff_t offset, id _Nullable value, bool atomic, signed char copy); extern void glue_objc_getPropertyStruct PPC_PARAMS(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong); extern void glue_objc_setPropertyStruct PPC_PARAMS(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong); extern void glue_objc_enumerationMutation PPC_PARAMS(id _Nonnull object); extern int glue___gnu_objc_personality PPC_PARAMS(int version, int actions, uint64_t *_Nonnull exClass, void *_Nonnull ex, void *_Nonnull ctx); extern id _Nullable glue_objc_retain PPC_PARAMS(id _Nullable object); extern id _Nullable glue_objc_retainBlock PPC_PARAMS(id _Nullable block); extern id _Nullable glue_objc_retainAutorelease PPC_PARAMS(id _Nullable object); extern void glue_objc_release PPC_PARAMS(id _Nullable object); extern id _Nullable glue_objc_autorelease PPC_PARAMS(id _Nullable object); extern id _Nullable glue_objc_autoreleaseReturnValue PPC_PARAMS(id _Nullable object); extern id _Nullable glue_objc_retainAutoreleaseReturnValue PPC_PARAMS(id _Nullable object); extern id _Nullable glue_objc_retainAutoreleasedReturnValue PPC_PARAMS(id _Nullable object); extern id _Nullable glue_objc_storeStrong PPC_PARAMS(id _Nullable *_Nonnull object, id _Nullable value); extern id _Nullable glue_objc_storeWeak PPC_PARAMS(id _Nullable *_Nonnull object, id _Nullable value); extern id _Nullable glue_objc_loadWeakRetained PPC_PARAMS(id _Nullable *_Nonnull object); extern id _Nullable glue_objc_initWeak PPC_PARAMS(id _Nullable *_Nonnull object, id _Nullable value); extern void glue_objc_destroyWeak PPC_PARAMS(id _Nullable *_Nonnull object); extern id _Nullable glue_objc_loadWeak PPC_PARAMS(id _Nullable *_Nonnull object); extern void glue_objc_copyWeak PPC_PARAMS(id _Nullable *_Nonnull dest, id _Nullable *_Nonnull src); extern void glue_objc_moveWeak PPC_PARAMS(id _Nullable *_Nonnull dest, id _Nullable *_Nonnull src); extern SEL _Nonnull glue_sel_registerName PPC_PARAMS(const char *_Nonnull name); extern const char *_Nonnull glue_sel_getName PPC_PARAMS(SEL _Nonnull selector); extern bool glue_sel_isEqual PPC_PARAMS(SEL _Nonnull selector1, SEL _Nonnull selector2); extern Class _Nonnull glue_objc_allocateClassPair PPC_PARAMS(Class _Nullable superclass, const char *_Nonnull name, size_t extraBytes); extern void glue_objc_registerClassPair PPC_PARAMS(Class _Nonnull class); extern unsigned int glue_objc_getClassList PPC_PARAMS(Class _Nonnull *_Nullable buffer, unsigned int count); extern Class _Nonnull *_Nonnull glue_objc_copyClassList PPC_PARAMS(unsigned int *_Nullable length); extern bool glue_class_isMetaClass PPC_PARAMS(Class _Nullable class); extern const char *_Nullable glue_class_getName PPC_PARAMS(Class _Nullable class); extern Class _Nullable glue_class_getSuperclass PPC_PARAMS(Class _Nullable class); extern unsigned long glue_class_getInstanceSize PPC_PARAMS(Class _Nullable class); extern bool glue_class_respondsToSelector PPC_PARAMS(Class _Nullable class, SEL _Nonnull selector); extern bool glue_class_conformsToProtocol PPC_PARAMS(Class _Nullable class, Protocol *_Nonnull p); extern IMP _Nullable glue_class_getMethodImplementation PPC_PARAMS(Class _Nullable class, SEL _Nonnull selector); extern IMP _Nullable glue_class_getMethodImplementation_stret PPC_PARAMS(Class _Nullable class, SEL _Nonnull selector); extern Method _Nullable glue_class_getInstanceMethod PPC_PARAMS(Class _Nullable class, SEL _Nonnull selector); extern bool glue_class_addMethod PPC_PARAMS(Class _Nonnull class, SEL _Nonnull selector, IMP _Nonnull implementation, const char *_Nullable typeEncoding); extern IMP _Nullable glue_class_replaceMethod PPC_PARAMS(Class _Nonnull class, SEL _Nonnull selector, IMP _Nonnull implementation, const char *_Nullable typeEncoding); extern Class _Nullable glue_object_getClass PPC_PARAMS(id _Nullable object); extern Class _Nullable glue_object_setClass PPC_PARAMS(id _Nullable object, Class _Nonnull class); extern const char *_Nullable glue_object_getClassName PPC_PARAMS(id _Nullable object); extern const char *_Nonnull glue_protocol_getName PPC_PARAMS(Protocol *_Nonnull protocol); extern bool glue_protocol_isEqual PPC_PARAMS(Protocol *_Nonnull protocol1, Protocol *_Nonnull protocol2); extern bool glue_protocol_conformsToProtocol PPC_PARAMS(Protocol *_Nonnull protocol1, Protocol *_Nonnull protocol2); extern _Nullable objc_uncaught_exception_handler glue_objc_setUncaughtExceptionHandler PPC_PARAMS(objc_uncaught_exception_handler _Nullable handler); extern void glue_objc_setForwardHandler PPC_PARAMS(IMP _Nullable forward, IMP _Nullable stretForward); extern void glue_objc_setEnumerationMutationHandler PPC_PARAMS(objc_enumeration_mutation_handler _Nullable hadler); extern id _Nullable glue_objc_constructInstance PPC_PARAMS(Class _Nullable class, void *_Nullable bytes); extern void glue_objc_deinit(void); extern Ivar _Nullable *_Nullable glue_class_copyIvarList PPC_PARAMS(Class _Nullable class, unsigned int *_Nullable outCount); extern const char *_Nonnull glue_ivar_getName PPC_PARAMS(Ivar _Nonnull ivar); extern const char *_Nonnull glue_ivar_getTypeEncoding PPC_PARAMS(Ivar _Nonnull ivar); extern ptrdiff_t glue_ivar_getOffset PPC_PARAMS(Ivar _Nonnull ivar); extern Method _Nullable *_Nullable glue_class_copyMethodList PPC_PARAMS(Class _Nullable class, unsigned int *_Nullable outCount); extern SEL _Nonnull glue_method_getName PPC_PARAMS(Method _Nonnull method); extern const char *_Nullable glue_method_getTypeEncoding PPC_PARAMS(Method _Nonnull method); extern objc_property_t _Nullable *_Nullable glue_class_copyPropertyList PPC_PARAMS(Class _Nullable class, unsigned int *_Nullable outCount); extern const char *_Nonnull glue_property_getName PPC_PARAMS(objc_property_t _Nonnull property); extern char *_Nullable glue_property_copyAttributeValue PPC_PARAMS(objc_property_t _Nonnull property, const char *_Nonnull name); extern void *_Nullable glue_objc_destructInstance PPC_PARAMS(id _Nullable object); extern void *_Null_unspecified glue_objc_autoreleasePoolPush(void); extern void glue_objc_autoreleasePoolPop PPC_PARAMS(void *_Null_unspecified pool); extern id _Nullable glue__objc_rootAutorelease PPC_PARAMS(id _Nullable object); extern struct objc_hashtable *_Nonnull glue_objc_hashtable_new PPC_PARAMS(objc_hashtable_hash_func hash, objc_hashtable_equal_func equal, uint32_t size); extern void glue_objc_hashtable_set PPC_PARAMS(struct objc_hashtable *_Nonnull table, const void *_Nonnull key, const void *_Nonnull object); extern void *_Nullable glue_objc_hashtable_get PPC_PARAMS(struct objc_hashtable *_Nonnull table, const void *_Nonnull key); extern void glue_objc_hashtable_delete PPC_PARAMS(struct objc_hashtable *_Nonnull table, const void *_Nonnull key); extern void glue_objc_hashtable_free PPC_PARAMS(struct objc_hashtable *_Nonnull table); extern void glue_objc_setTaggedPointerSecret PPC_PARAMS(uintptr_t secret); extern int glue_objc_registerTaggedPointerClass PPC_PARAMS(Class _Nonnull class); extern bool glue_object_isTaggedPointer PPC_PARAMS(id _Nullable object); extern uintptr_t glue_object_getTaggedPointerValue PPC_PARAMS(id _Nonnull object); extern id _Nullable glue_objc_createTaggedPointer PPC_PARAMS(int class, uintptr_t value); |
Modified src/runtime/amiga-glue.m from [896aceecb7] to [8e4bfceffc].
1 | /* | < < | | < < | < < < < < < < | < | < < < | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | < < | | | | | | < | | < | | | | | < | | | < | | | | | < | | | < < < < < < | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | < | | | | | < | | | | | | | | | | | | | | | | | < | | | | < | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | < | < | | | | | < | | | < | | | | | | | | < < < < < < < < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ /* This file is automatically generated from amiga-library.xml */ #include "config.h" #import "amiga-glue.h" #ifdef OF_MORPHOS /* All __saveds functions in this file need to use the SysV ABI */ __asm__ ( ".section .text\n" ".align 2\n" "__restore_r13:\n" " lwz %r13, 44(%r12)\n" " blr\n" ); #endif bool __saveds glue_objc_init PPC_PARAMS(unsigned int version, struct objc_libc *libc) { M68K_ARG(unsigned int, version, d0) M68K_ARG(struct objc_libc *, libc, a0) return objc_init(version, libc); } void __saveds glue___objc_exec_class PPC_PARAMS(struct objc_module *_Nonnull module) { M68K_ARG(struct objc_module *_Nonnull, module, a0) __objc_exec_class(module); } IMP _Nonnull __saveds glue_objc_msg_lookup PPC_PARAMS(id _Nullable object, SEL _Nonnull selector) { M68K_ARG(id _Nullable, object, a0) M68K_ARG(SEL _Nonnull, selector, a1) return objc_msg_lookup(object, selector); } IMP _Nonnull __saveds glue_objc_msg_lookup_stret PPC_PARAMS(id _Nullable object, SEL _Nonnull selector) { M68K_ARG(id _Nullable, object, a0) M68K_ARG(SEL _Nonnull, selector, a1) return objc_msg_lookup_stret(object, selector); } IMP _Nonnull __saveds glue_objc_msg_lookup_super PPC_PARAMS(struct objc_super *_Nonnull super, SEL _Nonnull selector) { M68K_ARG(struct objc_super *_Nonnull, super, a0) M68K_ARG(SEL _Nonnull, selector, a1) return objc_msg_lookup_super(super, selector); } IMP _Nonnull __saveds glue_objc_msg_lookup_super_stret PPC_PARAMS(struct objc_super *_Nonnull super, SEL _Nonnull selector) { M68K_ARG(struct objc_super *_Nonnull, super, a0) M68K_ARG(SEL _Nonnull, selector, a1) return objc_msg_lookup_super_stret(super, selector); } Class _Nullable __saveds glue_objc_lookUpClass PPC_PARAMS(const char *_Nonnull name) { M68K_ARG(const char *_Nonnull, name, a0) return objc_lookUpClass(name); } Class _Nullable __saveds glue_objc_getClass PPC_PARAMS(const char *_Nonnull name) { M68K_ARG(const char *_Nonnull, name, a0) return objc_getClass(name); } Class _Nonnull __saveds glue_objc_getRequiredClass PPC_PARAMS(const char *_Nonnull name) { M68K_ARG(const char *_Nonnull, name, a0) return objc_getRequiredClass(name); } Class _Nullable __saveds glue_objc_lookup_class PPC_PARAMS(const char *_Nonnull name) { M68K_ARG(const char *_Nonnull, name, a0) return objc_lookup_class(name); } Class _Nonnull __saveds glue_objc_get_class PPC_PARAMS(const char *_Nonnull name) { M68K_ARG(const char *_Nonnull, name, a0) return objc_get_class(name); } void __saveds glue_objc_exception_throw PPC_PARAMS(id _Nonnull object) { M68K_ARG(id _Nonnull, object, a0) objc_exception_throw(object); } int __saveds glue_objc_sync_enter PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return objc_sync_enter(object); } int __saveds glue_objc_sync_exit PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return objc_sync_exit(object); } id _Nullable __saveds glue_objc_getProperty PPC_PARAMS(id _Nonnull self, SEL _Nonnull _cmd, ptrdiff_t offset, bool atomic) { M68K_ARG(id _Nonnull, self, a0) M68K_ARG(SEL _Nonnull, _cmd, a1) M68K_ARG(ptrdiff_t, offset, d0) M68K_ARG(bool, atomic, d1) return objc_getProperty(self, _cmd, offset, atomic); } void __saveds glue_objc_setProperty PPC_PARAMS(id _Nonnull self, SEL _Nonnull _cmd, ptrdiff_t offset, id _Nullable value, bool atomic, signed char copy) { M68K_ARG(id _Nonnull, self, a0) M68K_ARG(SEL _Nonnull, _cmd, a1) M68K_ARG(ptrdiff_t, offset, d0) M68K_ARG(id _Nullable, value, a2) M68K_ARG(bool, atomic, d1) M68K_ARG(signed char, copy, d2) objc_setProperty(self, _cmd, offset, value, atomic, copy); } void __saveds glue_objc_getPropertyStruct PPC_PARAMS(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong) { M68K_ARG(void *_Nonnull, dest, a0) M68K_ARG(const void *_Nonnull, src, a1) M68K_ARG(ptrdiff_t, size, d0) M68K_ARG(bool, atomic, d1) M68K_ARG(bool, strong, d2) objc_getPropertyStruct(dest, src, size, atomic, strong); } void __saveds glue_objc_setPropertyStruct PPC_PARAMS(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong) { M68K_ARG(void *_Nonnull, dest, a0) M68K_ARG(const void *_Nonnull, src, a1) M68K_ARG(ptrdiff_t, size, d0) M68K_ARG(bool, atomic, d1) M68K_ARG(bool, strong, d2) objc_setPropertyStruct(dest, src, size, atomic, strong); } void __saveds glue_objc_enumerationMutation PPC_PARAMS(id _Nonnull object) { M68K_ARG(id _Nonnull, object, a0) objc_enumerationMutation(object); } int __saveds glue___gnu_objc_personality PPC_PARAMS(int version, int actions, uint64_t *_Nonnull exClass, void *_Nonnull ex, void *_Nonnull ctx) { M68K_ARG(int, version, d0) M68K_ARG(int, actions, d1) M68K_ARG(uint64_t *_Nonnull, exClass, d2) M68K_ARG(void *_Nonnull, ex, a0) M68K_ARG(void *_Nonnull, ctx, a1) return __gnu_objc_personality(version, actions, exClass, ex, ctx); } id _Nullable __saveds glue_objc_retain PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return objc_retain(object); } id _Nullable __saveds glue_objc_retainBlock PPC_PARAMS(id _Nullable block) { M68K_ARG(id _Nullable, block, a0) return objc_retainBlock(block); } id _Nullable __saveds glue_objc_retainAutorelease PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return objc_retainAutorelease(object); } void __saveds glue_objc_release PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) objc_release(object); } id _Nullable __saveds glue_objc_autorelease PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return objc_autorelease(object); } id _Nullable __saveds glue_objc_autoreleaseReturnValue PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return objc_autoreleaseReturnValue(object); } id _Nullable __saveds glue_objc_retainAutoreleaseReturnValue PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return objc_retainAutoreleaseReturnValue(object); } id _Nullable __saveds glue_objc_retainAutoreleasedReturnValue PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return objc_retainAutoreleasedReturnValue(object); } id _Nullable __saveds glue_objc_storeStrong PPC_PARAMS(id _Nullable *_Nonnull object, id _Nullable value) { M68K_ARG(id _Nullable *_Nonnull, object, a0) M68K_ARG(id _Nullable, value, a1) return objc_storeStrong(object, value); } id _Nullable __saveds glue_objc_storeWeak PPC_PARAMS(id _Nullable *_Nonnull object, id _Nullable value) { M68K_ARG(id _Nullable *_Nonnull, object, a0) M68K_ARG(id _Nullable, value, a1) return objc_storeWeak(object, value); } id _Nullable __saveds glue_objc_loadWeakRetained PPC_PARAMS(id _Nullable *_Nonnull object) { M68K_ARG(id _Nullable *_Nonnull, object, a0) return objc_loadWeakRetained(object); } id _Nullable __saveds glue_objc_initWeak PPC_PARAMS(id _Nullable *_Nonnull object, id _Nullable value) { M68K_ARG(id _Nullable *_Nonnull, object, a0) M68K_ARG(id _Nullable, value, a1) return objc_initWeak(object, value); } void __saveds glue_objc_destroyWeak PPC_PARAMS(id _Nullable *_Nonnull object) { M68K_ARG(id _Nullable *_Nonnull, object, a0) objc_destroyWeak(object); } id _Nullable __saveds glue_objc_loadWeak PPC_PARAMS(id _Nullable *_Nonnull object) { M68K_ARG(id _Nullable *_Nonnull, object, a0) return objc_loadWeak(object); } void __saveds glue_objc_copyWeak PPC_PARAMS(id _Nullable *_Nonnull dest, id _Nullable *_Nonnull src) { M68K_ARG(id _Nullable *_Nonnull, dest, a0) M68K_ARG(id _Nullable *_Nonnull, src, a1) objc_copyWeak(dest, src); } void __saveds glue_objc_moveWeak PPC_PARAMS(id _Nullable *_Nonnull dest, id _Nullable *_Nonnull src) { M68K_ARG(id _Nullable *_Nonnull, dest, a0) M68K_ARG(id _Nullable *_Nonnull, src, a1) objc_moveWeak(dest, src); } SEL _Nonnull __saveds glue_sel_registerName PPC_PARAMS(const char *_Nonnull name) { M68K_ARG(const char *_Nonnull, name, a0) return sel_registerName(name); } const char *_Nonnull __saveds glue_sel_getName PPC_PARAMS(SEL _Nonnull selector) { M68K_ARG(SEL _Nonnull, selector, a0) return sel_getName(selector); } bool __saveds glue_sel_isEqual PPC_PARAMS(SEL _Nonnull selector1, SEL _Nonnull selector2) { M68K_ARG(SEL _Nonnull, selector1, a0) M68K_ARG(SEL _Nonnull, selector2, a1) return sel_isEqual(selector1, selector2); } Class _Nonnull __saveds glue_objc_allocateClassPair PPC_PARAMS(Class _Nullable superclass, const char *_Nonnull name, size_t extraBytes) { M68K_ARG(Class _Nullable, superclass, a0) M68K_ARG(const char *_Nonnull, name, a1) M68K_ARG(size_t, extraBytes, d0) return objc_allocateClassPair(superclass, name, extraBytes); } void __saveds glue_objc_registerClassPair PPC_PARAMS(Class _Nonnull class) { M68K_ARG(Class _Nonnull, class, a0) objc_registerClassPair(class); } unsigned int __saveds glue_objc_getClassList PPC_PARAMS(Class _Nonnull *_Nullable buffer, unsigned int count) { M68K_ARG(Class _Nonnull *_Nullable, buffer, a0) M68K_ARG(unsigned int, count, d0) return objc_getClassList(buffer, count); } Class _Nonnull *_Nonnull __saveds glue_objc_copyClassList PPC_PARAMS(unsigned int *_Nullable length) { M68K_ARG(unsigned int *_Nullable, length, a0) return objc_copyClassList(length); } bool __saveds glue_class_isMetaClass PPC_PARAMS(Class _Nullable class) { M68K_ARG(Class _Nullable, class, a0) return class_isMetaClass(class); } const char *_Nullable __saveds glue_class_getName PPC_PARAMS(Class _Nullable class) { M68K_ARG(Class _Nullable, class, a0) return class_getName(class); } Class _Nullable __saveds glue_class_getSuperclass PPC_PARAMS(Class _Nullable class) { M68K_ARG(Class _Nullable, class, a0) return class_getSuperclass(class); } unsigned long __saveds glue_class_getInstanceSize PPC_PARAMS(Class _Nullable class) { M68K_ARG(Class _Nullable, class, a0) return class_getInstanceSize(class); } bool __saveds glue_class_respondsToSelector PPC_PARAMS(Class _Nullable class, SEL _Nonnull selector) { M68K_ARG(Class _Nullable, class, a0) M68K_ARG(SEL _Nonnull, selector, a1) return class_respondsToSelector(class, selector); } bool __saveds glue_class_conformsToProtocol PPC_PARAMS(Class _Nullable class, Protocol *_Nonnull p) { M68K_ARG(Class _Nullable, class, a0) M68K_ARG(Protocol *_Nonnull, p, a1) return class_conformsToProtocol(class, p); } IMP _Nullable __saveds glue_class_getMethodImplementation PPC_PARAMS(Class _Nullable class, SEL _Nonnull selector) { M68K_ARG(Class _Nullable, class, a0) M68K_ARG(SEL _Nonnull, selector, a1) return class_getMethodImplementation(class, selector); } IMP _Nullable __saveds glue_class_getMethodImplementation_stret PPC_PARAMS(Class _Nullable class, SEL _Nonnull selector) { M68K_ARG(Class _Nullable, class, a0) M68K_ARG(SEL _Nonnull, selector, a1) return class_getMethodImplementation_stret(class, selector); } Method _Nullable __saveds glue_class_getInstanceMethod PPC_PARAMS(Class _Nullable class, SEL _Nonnull selector) { M68K_ARG(Class _Nullable, class, a0) M68K_ARG(SEL _Nonnull, selector, a1) return class_getInstanceMethod(class, selector); } bool __saveds glue_class_addMethod PPC_PARAMS(Class _Nonnull class, SEL _Nonnull selector, IMP _Nonnull implementation, const char *_Nullable typeEncoding) { M68K_ARG(Class _Nonnull, class, a0) M68K_ARG(SEL _Nonnull, selector, a1) M68K_ARG(IMP _Nonnull, implementation, a2) M68K_ARG(const char *_Nullable, typeEncoding, a3) return class_addMethod(class, selector, implementation, typeEncoding); } IMP _Nullable __saveds glue_class_replaceMethod PPC_PARAMS(Class _Nonnull class, SEL _Nonnull selector, IMP _Nonnull implementation, const char *_Nullable typeEncoding) { M68K_ARG(Class _Nonnull, class, a0) M68K_ARG(SEL _Nonnull, selector, a1) M68K_ARG(IMP _Nonnull, implementation, a2) M68K_ARG(const char *_Nullable, typeEncoding, a3) return class_replaceMethod(class, selector, implementation, typeEncoding); } Class _Nullable __saveds glue_object_getClass PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return object_getClass(object); } Class _Nullable __saveds glue_object_setClass PPC_PARAMS(id _Nullable object, Class _Nonnull class) { M68K_ARG(id _Nullable, object, a0) M68K_ARG(Class _Nonnull, class, a1) return object_setClass(object, class); } const char *_Nullable __saveds glue_object_getClassName PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return object_getClassName(object); } const char *_Nonnull __saveds glue_protocol_getName PPC_PARAMS(Protocol *_Nonnull protocol) { M68K_ARG(Protocol *_Nonnull, protocol, a0) return protocol_getName(protocol); } bool __saveds glue_protocol_isEqual PPC_PARAMS(Protocol *_Nonnull protocol1, Protocol *_Nonnull protocol2) { M68K_ARG(Protocol *_Nonnull, protocol1, a0) M68K_ARG(Protocol *_Nonnull, protocol2, a1) return protocol_isEqual(protocol1, protocol2); } bool __saveds glue_protocol_conformsToProtocol PPC_PARAMS(Protocol *_Nonnull protocol1, Protocol *_Nonnull protocol2) { M68K_ARG(Protocol *_Nonnull, protocol1, a0) M68K_ARG(Protocol *_Nonnull, protocol2, a1) return protocol_conformsToProtocol(protocol1, protocol2); } _Nullable objc_uncaught_exception_handler __saveds glue_objc_setUncaughtExceptionHandler PPC_PARAMS(objc_uncaught_exception_handler _Nullable handler) { M68K_ARG(objc_uncaught_exception_handler _Nullable, handler, a0) return objc_setUncaughtExceptionHandler(handler); } void __saveds glue_objc_setForwardHandler PPC_PARAMS(IMP _Nullable forward, IMP _Nullable stretForward) { M68K_ARG(IMP _Nullable, forward, a0) M68K_ARG(IMP _Nullable, stretForward, a1) objc_setForwardHandler(forward, stretForward); } void __saveds glue_objc_setEnumerationMutationHandler PPC_PARAMS(objc_enumeration_mutation_handler _Nullable hadler) { M68K_ARG(objc_enumeration_mutation_handler _Nullable, hadler, a0) objc_setEnumerationMutationHandler(hadler); } id _Nullable __saveds glue_objc_constructInstance PPC_PARAMS(Class _Nullable class, void *_Nullable bytes) { M68K_ARG(Class _Nullable, class, a0) M68K_ARG(void *_Nullable, bytes, a1) return objc_constructInstance(class, bytes); } void __saveds glue_objc_deinit(void) { objc_deinit(); } Ivar _Nullable *_Nullable __saveds glue_class_copyIvarList PPC_PARAMS(Class _Nullable class, unsigned int *_Nullable outCount) { M68K_ARG(Class _Nullable, class, a0) M68K_ARG(unsigned int *_Nullable, outCount, a1) return class_copyIvarList(class, outCount); } const char *_Nonnull __saveds glue_ivar_getName PPC_PARAMS(Ivar _Nonnull ivar) { M68K_ARG(Ivar _Nonnull, ivar, a0) return ivar_getName(ivar); } const char *_Nonnull __saveds glue_ivar_getTypeEncoding PPC_PARAMS(Ivar _Nonnull ivar) { M68K_ARG(Ivar _Nonnull, ivar, a0) return ivar_getTypeEncoding(ivar); } ptrdiff_t __saveds glue_ivar_getOffset PPC_PARAMS(Ivar _Nonnull ivar) { M68K_ARG(Ivar _Nonnull, ivar, a0) return ivar_getOffset(ivar); } Method _Nullable *_Nullable __saveds glue_class_copyMethodList PPC_PARAMS(Class _Nullable class, unsigned int *_Nullable outCount) { M68K_ARG(Class _Nullable, class, a0) M68K_ARG(unsigned int *_Nullable, outCount, a1) return class_copyMethodList(class, outCount); } SEL _Nonnull __saveds glue_method_getName PPC_PARAMS(Method _Nonnull method) { M68K_ARG(Method _Nonnull, method, a0) return method_getName(method); } const char *_Nullable __saveds glue_method_getTypeEncoding PPC_PARAMS(Method _Nonnull method) { M68K_ARG(Method _Nonnull, method, a0) return method_getTypeEncoding(method); } objc_property_t _Nullable *_Nullable __saveds glue_class_copyPropertyList PPC_PARAMS(Class _Nullable class, unsigned int *_Nullable outCount) { M68K_ARG(Class _Nullable, class, a0) M68K_ARG(unsigned int *_Nullable, outCount, a1) return class_copyPropertyList(class, outCount); } const char *_Nonnull __saveds glue_property_getName PPC_PARAMS(objc_property_t _Nonnull property) { M68K_ARG(objc_property_t _Nonnull, property, a0) return property_getName(property); } char *_Nullable __saveds glue_property_copyAttributeValue PPC_PARAMS(objc_property_t _Nonnull property, const char *_Nonnull name) { M68K_ARG(objc_property_t _Nonnull, property, a0) M68K_ARG(const char *_Nonnull, name, a1) return property_copyAttributeValue(property, name); } void *_Nullable __saveds glue_objc_destructInstance PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return objc_destructInstance(object); } void *_Null_unspecified __saveds glue_objc_autoreleasePoolPush(void) { return objc_autoreleasePoolPush(); } void __saveds glue_objc_autoreleasePoolPop PPC_PARAMS(void *_Null_unspecified pool) { M68K_ARG(void *_Null_unspecified, pool, a0) objc_autoreleasePoolPop(pool); } id _Nullable __saveds glue__objc_rootAutorelease PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return _objc_rootAutorelease(object); } struct objc_hashtable *_Nonnull __saveds glue_objc_hashtable_new PPC_PARAMS(objc_hashtable_hash_func hash, objc_hashtable_equal_func equal, uint32_t size) { M68K_ARG(objc_hashtable_hash_func, hash, a0) M68K_ARG(objc_hashtable_equal_func, equal, a1) M68K_ARG(uint32_t, size, d0) return objc_hashtable_new(hash, equal, size); } void __saveds glue_objc_hashtable_set PPC_PARAMS(struct objc_hashtable *_Nonnull table, const void *_Nonnull key, const void *_Nonnull object) { M68K_ARG(struct objc_hashtable *_Nonnull, table, a0) M68K_ARG(const void *_Nonnull, key, a1) M68K_ARG(const void *_Nonnull, object, a2) objc_hashtable_set(table, key, object); } void *_Nullable __saveds glue_objc_hashtable_get PPC_PARAMS(struct objc_hashtable *_Nonnull table, const void *_Nonnull key) { M68K_ARG(struct objc_hashtable *_Nonnull, table, a0) M68K_ARG(const void *_Nonnull, key, a1) return objc_hashtable_get(table, key); } void __saveds glue_objc_hashtable_delete PPC_PARAMS(struct objc_hashtable *_Nonnull table, const void *_Nonnull key) { M68K_ARG(struct objc_hashtable *_Nonnull, table, a0) M68K_ARG(const void *_Nonnull, key, a1) objc_hashtable_delete(table, key); } void __saveds glue_objc_hashtable_free PPC_PARAMS(struct objc_hashtable *_Nonnull table) { M68K_ARG(struct objc_hashtable *_Nonnull, table, a0) objc_hashtable_free(table); } void __saveds glue_objc_setTaggedPointerSecret PPC_PARAMS(uintptr_t secret) { M68K_ARG(uintptr_t, secret, d0) objc_setTaggedPointerSecret(secret); } int __saveds glue_objc_registerTaggedPointerClass PPC_PARAMS(Class _Nonnull class) { M68K_ARG(Class _Nonnull, class, a0) return objc_registerTaggedPointerClass(class); } bool __saveds glue_object_isTaggedPointer PPC_PARAMS(id _Nullable object) { M68K_ARG(id _Nullable, object, a0) return object_isTaggedPointer(object); } uintptr_t __saveds glue_object_getTaggedPointerValue PPC_PARAMS(id _Nonnull object) { M68K_ARG(id _Nonnull, object, a0) return object_getTaggedPointerValue(object); } id _Nullable __saveds glue_objc_createTaggedPointer PPC_PARAMS(int class, uintptr_t value) { M68K_ARG(int, class, d0) M68K_ARG(uintptr_t, value, d1) return objc_createTaggedPointer(class, value); } |
Modified src/runtime/amiga-library.m from [3b48513197] to [d177a01899].
1 | /* | < < | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "ObjFWRT.h" #import "private.h" #import "amiga-glue.h" #include <exec/libraries.h> #include <exec/nodes.h> #include <exec/resident.h> #include <proto/exec.h> #define CONCAT_VERSION2(major, minor) #major "." #minor |
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | /* This always needs to be the first thing in the file. */ int _start() { return -1; } struct ObjFWRTBase { struct Library library; void *segList; struct ObjFWRTBase *parent; char *dataSeg; bool initialized; }; #ifdef OF_AMIGAOS_M68K extern uintptr_t __CTOR_LIST__[]; extern const void *_EH_FRAME_BEGINS__; extern void *_EH_FRAME_OBJECTS__; #endif | > > > > > > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | /* This always needs to be the first thing in the file. */ int _start() { return -1; } #ifdef OF_AMIGAOS_M68K void __init_eh(void) { } #endif struct ObjFWRTBase { struct Library library; void *segList; struct ObjFWRTBase *parent; char *dataSeg; bool initialized; }; #ifdef OF_AMIGAOS_M68K extern uintptr_t __CTOR_LIST__[]; extern const void *_EH_FRAME_BEGINS__; extern void *_EH_FRAME_OBJECTS__; #endif #ifdef OF_MORPHOS const ULONG __abox__ = 1; #endif struct ExecBase *SysBase; struct objc_libc libc; #if defined(OF_AMIGAOS_M68K) __asm__ ( ".text\n" ".globl ___restore_a4\n" ".align 1\n" "___restore_a4:\n" |
︙ | ︙ | |||
327 328 329 330 331 332 333 | child->dataSeg += DATA_OFFSET; return &child->library; } static void * | | > > | > > > > > > > | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | child->dataSeg += DATA_OFFSET; return &child->library; } static void * expunge(struct ObjFWRTBase *base, struct ExecBase *sysBase) { #define SysBase sysBase void *segList; if (base->parent != NULL) { base->parent->library.lib_Flags |= LIBF_DELEXP; return 0; } if (base->library.lib_OpenCnt > 0) { base->library.lib_Flags |= LIBF_DELEXP; return 0; } segList = base->segList; Remove(&base->library.lib_Node); FreeMem((char *)base - base->library.lib_NegSize, base->library.lib_NegSize + base->library.lib_PosSize); return segList; #undef SysBase } static void *__saveds lib_expunge(void) { OBJC_M68K_ARG(struct ObjFWRTBase *, base, a6) return expunge(base, SysBase); } static void *__saveds lib_close(void) { /* * SysBase becomes invalid during this function, so we store it in * sysBase and add a define to make the inlines use the right one. */ struct ExecBase *sysBase = SysBase; #define SysBase sysBase OBJC_M68K_ARG(struct ObjFWRTBase *, base, a6) if (base->parent != NULL) { struct ObjFWRTBase *parent; #ifdef OF_AMIGAOS_M68K if (base->initialized) |
︙ | ︙ | |||
384 385 386 387 388 389 390 | base->library.lib_NegSize + base->library.lib_PosSize); base = parent; } if (--base->library.lib_OpenCnt == 0 && (base->library.lib_Flags & LIBF_DELEXP)) | | > | < > > > < < | | > > | > > | 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | base->library.lib_NegSize + base->library.lib_PosSize); base = parent; } if (--base->library.lib_OpenCnt == 0 && (base->library.lib_Flags & LIBF_DELEXP)) return expunge(base, sysBase); return NULL; #undef SysBase } static void * lib_null(void) { return NULL; } bool objc_init(unsigned int version, struct objc_libc *libc_) { #ifdef OF_AMIGAOS_M68K OBJC_M68K_ARG(struct ObjFWRTBase *, base, a6) #else register struct ObjFWRTBase *r12 __asm__("r12"); struct ObjFWRTBase *base = r12; #endif #ifdef OF_MORPHOS void *frame; #endif uintptr_t *iter, *iter0; if (version > 1) return false; memcpy(&libc, libc_, sizeof(libc)); #ifdef OF_AMIGAOS_M68K if ((size_t)_EH_FRAME_BEGINS__ != (size_t)_EH_FRAME_OBJECTS__) return false; for (size_t i = 1; i <= (size_t)_EH_FRAME_BEGINS__; i++) libc.__register_frame_info((&_EH_FRAME_BEGINS__)[i], (&_EH_FRAME_OBJECTS__)[i]); iter0 = &__CTOR_LIST__[1]; #elif defined(OF_MORPHOS) __asm__ ( "lis %0, __EH_FRAME_BEGIN__@ha\n\t" "la %0, __EH_FRAME_BEGIN__@l(%0)\n\t" "lis %1, __CTOR_LIST__@ha\n\t" "la %1, __CTOR_LIST__@l(%1)\n\t" : "=r"(frame), "=r"(iter0) ); libc.__register_frame(frame); #endif for (iter = iter0; *iter != 0; iter++); while (iter > iter0) { void (*ctor)(void) = (void (*)(void))*--iter; ctor(); |
︙ | ︙ | |||
467 468 469 470 471 472 473 | void free(void *ptr) { libc.free(ptr); } | < < < < < < < < < < < < < < < < < < < < < < < < < < < | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | void free(void *ptr) { libc.free(ptr); } #ifdef HAVE_SJLJ_EXCEPTIONS int _Unwind_SjLj_RaiseException(void *ex) { return libc._Unwind_SjLj_RaiseException(ex); } #else |
︙ | ︙ | |||
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 | #else void _Unwind_Resume(void *ex) { libc._Unwind_Resume(ex); } #endif #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" static CONST_APTR functionTable[] = { #ifdef OF_MORPHOS (CONST_APTR)FUNCARRAY_BEGIN, (CONST_APTR)FUNCARRAY_32BIT_NATIVE, #endif (CONST_APTR)lib_open, (CONST_APTR)lib_close, (CONST_APTR)lib_expunge, (CONST_APTR)lib_null, #ifdef OF_MORPHOS (CONST_APTR)-1, (CONST_APTR)FUNCARRAY_32BIT_SYSTEMV, #endif | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 | #else void _Unwind_Resume(void *ex) { libc._Unwind_Resume(ex); } #endif #ifdef OF_AMIGAOS_M68K int snprintf(char *restrict str, size_t size, const char *restrict fmt, ...) { va_list args; int ret; va_start(args, fmt); ret = vsnprintf(str, size, fmt, args); va_end(args); return ret; } int vsnprintf(char *restrict str, size_t size, const char *restrict fmt, va_list args) { return libc.vsnprintf(str, size, fmt, args); } #endif int atexit(void (*function)(void)) { return libc.atexit(function); } void exit(int status) { libc.exit(status); OF_UNREACHABLE } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" static CONST_APTR functionTable[] = { #ifdef OF_MORPHOS (CONST_APTR)FUNCARRAY_BEGIN, (CONST_APTR)FUNCARRAY_32BIT_NATIVE, #endif (CONST_APTR)lib_open, (CONST_APTR)lib_close, (CONST_APTR)lib_expunge, (CONST_APTR)lib_null, #ifdef OF_MORPHOS (CONST_APTR)-1, (CONST_APTR)FUNCARRAY_32BIT_SYSTEMV, #endif #include "amiga-funcarray.inc" (CONST_APTR)-1, #ifdef OF_MORPHOS (CONST_APTR)FUNCARRAY_END #endif }; #pragma GCC diagnostic pop |
︙ | ︙ | |||
717 718 719 720 721 722 723 | #endif , .rt_Version = OBJFWRT_LIB_MAJOR, .rt_Type = NT_LIBRARY, .rt_Pri = 0, .rt_Name = (char *)OBJFWRT_AMIGA_LIB, .rt_IdString = (char *)"ObjFWRT " VERSION_STRING | | > > > > | | > | | 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 | #endif , .rt_Version = OBJFWRT_LIB_MAJOR, .rt_Type = NT_LIBRARY, .rt_Pri = 0, .rt_Name = (char *)OBJFWRT_AMIGA_LIB, .rt_IdString = (char *)"ObjFWRT " VERSION_STRING " \xA9 2008-2022 Jonathan Schleifer", .rt_Init = &init_table, #ifdef OF_MORPHOS .rt_Revision = OBJFWRT_LIB_MINOR, .rt_Tags = NULL, #endif }; #ifdef OF_MORPHOS __asm__ ( ".section .eh_frame, \"aw\"\n" ".globl __EH_FRAME_BEGIN__\n" ".type __EH_FRAME_BEGIN__, @object\n" "__EH_FRAME_BEGIN__:\n" ".section .ctors, \"aw\"\n" ".globl __CTOR_LIST__\n" ".type __CTOR_LIST__, @object\n" "__CTOR_LIST__:\n" ".section .text" ); #endif |
Added src/runtime/amiga-library.xml version [f6565586a9].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | <amiga-library version='1.0' base='ObjFWRTBase'> <include>ObjFWRT.h</include> <include>private.h</include> <!-- The following function is only for the linklib. --> <function name='objc_init' return-type='bool'> <argument name='version' type='unsigned int' m68k-reg='d0'/> <argument name='libc' type='struct objc_libc *' m68k-reg='a0'/> </function> <function name='__objc_exec_class'> <argument name='module' type='struct objc_module *_Nonnull' m68k-reg='a0'/> </function> <function name='objc_msg_lookup' return-type='IMP _Nonnull'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> <argument name='selector' type='SEL _Nonnull' m68k-reg='a1'/> </function> <function name='objc_msg_lookup_stret' return-type='IMP _Nonnull'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> <argument name='selector' type='SEL _Nonnull' m68k-reg='a1'/> </function> <function name='objc_msg_lookup_super' return-type='IMP _Nonnull'> <argument name='super' type='struct objc_super *_Nonnull' m68k-reg='a0'/> <argument name='selector' type='SEL _Nonnull' m68k-reg='a1'/> </function> <function name='objc_msg_lookup_super_stret' return-type='IMP _Nonnull'> <argument name='super' type='struct objc_super *_Nonnull' m68k-reg='a0'/> <argument name='selector' type='SEL _Nonnull' m68k-reg='a1'/> </function> <function name='objc_lookUpClass' return-type='Class _Nullable'> <argument name='name' type='const char *_Nonnull' m68k-reg='a0'/> </function> <function name='objc_getClass' return-type='Class _Nullable'> <argument name='name' type='const char *_Nonnull' m68k-reg='a0'/> </function> <function name='objc_getRequiredClass' return-type='Class _Nonnull'> <argument name='name' type='const char *_Nonnull' m68k-reg='a0'/> </function> <function name='objc_lookup_class' return-type='Class _Nullable'> <argument name='name' type='const char *_Nonnull' m68k-reg='a0'/> </function> <function name='objc_get_class' return-type='Class _Nonnull'> <argument name='name' type='const char *_Nonnull' m68k-reg='a0'/> </function> <function name='objc_exception_throw' noreturn='1'> <argument name='object' type='id _Nonnull' m68k-reg='a0'/> </function> <function name='objc_sync_enter' return-type='int'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='objc_sync_exit' return-type='int'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='objc_getProperty' return-type='id _Nullable'> <argument name='self' type='id _Nonnull' m68k-reg='a0'/> <argument name='_cmd' type='SEL _Nonnull' m68k-reg='a1'/> <argument name='offset' type='ptrdiff_t' m68k-reg='d0'/> <argument name='atomic' type='bool' m68k-reg='d1'/> </function> <function name='objc_setProperty'> <argument name='self' type='id _Nonnull' m68k-reg='a0'/> <argument name='_cmd' type='SEL _Nonnull' m68k-reg='a1'/> <argument name='offset' type='ptrdiff_t' m68k-reg='d0'/> <argument name='value' type='id _Nullable' m68k-reg='a2'/> <argument name='atomic' type='bool' m68k-reg='d1'/> <argument name='copy' type='signed char' m68k-reg='d2'/> </function> <function name='objc_getPropertyStruct'> <argument name='dest' type='void *_Nonnull' m68k-reg='a0'/> <argument name='src' type='const void *_Nonnull' m68k-reg='a1'/> <argument name='size' type='ptrdiff_t' m68k-reg='d0'/> <argument name='atomic' type='bool' m68k-reg='d1'/> <argument name='strong' type='bool' m68k-reg='d2'/> </function> <function name='objc_setPropertyStruct'> <argument name='dest' type='void *_Nonnull' m68k-reg='a0'/> <argument name='src' type='const void *_Nonnull' m68k-reg='a1'/> <argument name='size' type='ptrdiff_t' m68k-reg='d0'/> <argument name='atomic' type='bool' m68k-reg='d1'/> <argument name='strong' type='bool' m68k-reg='d2'/> </function> <function name='objc_enumerationMutation'> <argument name='object' type='id _Nonnull' m68k-reg='a0'/> </function> <function name='__gnu_objc_personality' return-type='int'> <argument name='version' type='int' m68k-reg='d0'/> <argument name='actions' type='int' m68k-reg='d1'/> <argument name='exClass' type='uint64_t *_Nonnull' m68k-reg='d2'/> <argument name='ex' type='void *_Nonnull' m68k-reg='a0'/> <argument name='ctx' type='void *_Nonnull' m68k-reg='a1'/> </function> <function name='objc_retain' return-type='id _Nullable'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='objc_retainBlock' return-type='id _Nullable'> <argument name='block' type='id _Nullable' m68k-reg='a0'/> </function> <function name='objc_retainAutorelease' return-type='id _Nullable'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='objc_release'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='objc_autorelease' return-type='id _Nullable'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='objc_autoreleaseReturnValue' return-type='id _Nullable'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='objc_retainAutoreleaseReturnValue' return-type='id _Nullable'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='objc_retainAutoreleasedReturnValue' return-type='id _Nullable'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='objc_storeStrong' return-type='id _Nullable'> <argument name='object' type='id _Nullable *_Nonnull' m68k-reg='a0'/> <argument name='value' type='id _Nullable' m68k-reg='a1'/> </function> <function name='objc_storeWeak' return-type='id _Nullable'> <argument name='object' type='id _Nullable *_Nonnull' m68k-reg='a0'/> <argument name='value' type='id _Nullable' m68k-reg='a1'/> </function> <function name='objc_loadWeakRetained' return-type='id _Nullable'> <argument name='object' type='id _Nullable *_Nonnull' m68k-reg='a0'/> </function> <function name='objc_initWeak' return-type='id _Nullable'> <argument name='object' type='id _Nullable *_Nonnull' m68k-reg='a0'/> <argument name='value' type='id _Nullable' m68k-reg='a1'/> </function> <function name='objc_destroyWeak'> <argument name='object' type='id _Nullable *_Nonnull' m68k-reg='a0'/> </function> <function name='objc_loadWeak' return-type='id _Nullable'> <argument name='object' type='id _Nullable *_Nonnull' m68k-reg='a0'/> </function> <function name='objc_copyWeak'> <argument name='dest' type='id _Nullable *_Nonnull' m68k-reg='a0'/> <argument name='src' type='id _Nullable *_Nonnull' m68k-reg='a1'/> </function> <function name='objc_moveWeak'> <argument name='dest' type='id _Nullable *_Nonnull' m68k-reg='a0'/> <argument name='src' type='id _Nullable *_Nonnull' m68k-reg='a1'/> </function> <function name='sel_registerName' return-type='SEL _Nonnull'> <argument name='name' type='const char *_Nonnull' m68k-reg='a0'/> </function> <function name='sel_getName' return-type='const char *_Nonnull'> <argument name='selector' type='SEL _Nonnull' m68k-reg='a0'/> </function> <function name='sel_isEqual' return-type='bool'> <argument name='selector1' type='SEL _Nonnull' m68k-reg='a0'/> <argument name='selector2' type='SEL _Nonnull' m68k-reg='a1'/> </function> <function name='objc_allocateClassPair' return-type='Class _Nonnull'> <argument name='superclass' type='Class _Nullable' m68k-reg='a0'/> <argument name='name' type='const char *_Nonnull' m68k-reg='a1'/> <argument name='extraBytes' type='size_t' m68k-reg='d0'/> </function> <function name='objc_registerClassPair'> <argument name='class' type='Class _Nonnull' m68k-reg='a0'/> </function> <function name='objc_getClassList' return-type='unsigned int'> <argument name='buffer' type='Class _Nonnull *_Nullable' m68k-reg='a0'/> <argument name='count' type='unsigned int' m68k-reg='d0'/> </function> <function name='objc_copyClassList' return-type='Class _Nonnull *_Nonnull'> <argument name='length' type='unsigned int *_Nullable' m68k-reg='a0'/> </function> <function name='class_isMetaClass' return-type='bool'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> </function> <function name='class_getName' return-type='const char *_Nullable'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> </function> <function name='class_getSuperclass' return-type='Class _Nullable'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> </function> <function name='class_getInstanceSize' return-type='unsigned long'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> </function> <function name='class_respondsToSelector' return-type='bool'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> <argument name='selector' type='SEL _Nonnull' m68k-reg='a1'/> </function> <function name='class_conformsToProtocol' return-type='bool'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> <argument name='p' type='Protocol *_Nonnull' m68k-reg='a1'/> </function> <function name='class_getMethodImplementation' return-type='IMP _Nullable'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> <argument name='selector' type='SEL _Nonnull' m68k-reg='a1'/> </function> <function name='class_getMethodImplementation_stret' return-type='IMP _Nullable'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> <argument name='selector' type='SEL _Nonnull' m68k-reg='a1'/> </function> <function name='class_getInstanceMethod' return-type='Method _Nullable'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> <argument name='selector' type='SEL _Nonnull' m68k-reg='a1'/> </function> <function name='class_addMethod' return-type='bool'> <argument name='class' type='Class _Nonnull' m68k-reg='a0'/> <argument name='selector' type='SEL _Nonnull' m68k-reg='a1'/> <argument name='implementation' type='IMP _Nonnull' m68k-reg='a2'/> <argument name='typeEncoding' type='const char *_Nullable' m68k-reg='a3'/> </function> <function name='class_replaceMethod' return-type='IMP _Nullable'> <argument name='class' type='Class _Nonnull' m68k-reg='a0'/> <argument name='selector' type='SEL _Nonnull' m68k-reg='a1'/> <argument name='implementation' type='IMP _Nonnull' m68k-reg='a2'/> <argument name='typeEncoding' type='const char *_Nullable' m68k-reg='a3'/> </function> <function name='object_getClass' return-type='Class _Nullable'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='object_setClass' return-type='Class _Nullable'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> <argument name='class' type='Class _Nonnull' m68k-reg='a1'/> </function> <function name='object_getClassName' return-type='const char *_Nullable'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='protocol_getName' return-type='const char *_Nonnull'> <argument name='protocol' type='Protocol *_Nonnull' m68k-reg='a0'/> </function> <function name='protocol_isEqual' return-type='bool'> <argument name='protocol1' type='Protocol *_Nonnull' m68k-reg='a0'/> <argument name='protocol2' type='Protocol *_Nonnull' m68k-reg='a1'/> </function> <function name='protocol_conformsToProtocol' return-type='bool'> <argument name='protocol1' type='Protocol *_Nonnull' m68k-reg='a0'/> <argument name='protocol2' type='Protocol *_Nonnull' m68k-reg='a1'/> </function> <function name='objc_setUncaughtExceptionHandler' return-type='_Nullable objc_uncaught_exception_handler'> <argument name='handler' type='objc_uncaught_exception_handler _Nullable' m68k-reg='a0'/> </function> <function name='objc_setForwardHandler'> <argument name='forward' type='IMP _Nullable' m68k-reg='a0'/> <argument name='stretForward' type='IMP _Nullable' m68k-reg='a1'/> </function> <function name='objc_setEnumerationMutationHandler'> <argument name='hadler' type='objc_enumeration_mutation_handler _Nullable' m68k-reg='a0'/> </function> <function name='objc_constructInstance' return-type='id _Nullable'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> <argument name='bytes' type='void *_Nullable' m68k-reg='a1'/> </function> <function name='objc_deinit'/> <function name='class_copyIvarList' return-type='Ivar _Nullable *_Nullable'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> <argument name='outCount' type='unsigned int *_Nullable' m68k-reg='a1'/> </function> <function name='ivar_getName' return-type='const char *_Nonnull'> <argument name='ivar' type='Ivar _Nonnull' m68k-reg='a0'/> </function> <function name='ivar_getTypeEncoding' return-type='const char *_Nonnull'> <argument name='ivar' type='Ivar _Nonnull' m68k-reg='a0'/> </function> <function name='ivar_getOffset' return-type='ptrdiff_t'> <argument name='ivar' type='Ivar _Nonnull' m68k-reg='a0'/> </function> <function name='class_copyMethodList' return-type='Method _Nullable *_Nullable'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> <argument name='outCount' type='unsigned int *_Nullable' m68k-reg='a1'/> </function> <function name='method_getName' return-type='SEL _Nonnull'> <argument name='method' type='Method _Nonnull' m68k-reg='a0'/> </function> <function name='method_getTypeEncoding' return-type='const char *_Nullable'> <argument name='method' type='Method _Nonnull' m68k-reg='a0'/> </function> <function name='class_copyPropertyList' return-type='objc_property_t _Nullable *_Nullable'> <argument name='class' type='Class _Nullable' m68k-reg='a0'/> <argument name='outCount' type='unsigned int *_Nullable' m68k-reg='a1'/> </function> <function name='property_getName' return-type='const char *_Nonnull'> <argument name='property' type='objc_property_t _Nonnull' m68k-reg='a0'/> </function> <function name='property_copyAttributeValue' return-type='char *_Nullable'> <argument name='property' type='objc_property_t _Nonnull' m68k-reg='a0'/> <argument name='name' type='const char *_Nonnull' m68k-reg='a1'/> </function> <function name='objc_destructInstance' return-type='void *_Nullable'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='objc_autoreleasePoolPush' return-type='void *_Null_unspecified'> </function> <function name='objc_autoreleasePoolPop'> <argument name='pool' type='void *_Null_unspecified' m68k-reg='a0'/> </function> <function name='_objc_rootAutorelease' return-type='id _Nullable'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <!-- The following functions are private! Don't use! --> <function name='objc_hashtable_new' return-type='struct objc_hashtable *_Nonnull'> <argument name='hash' type='objc_hashtable_hash_func' m68k-reg='a0'/> <argument name='equal' type='objc_hashtable_equal_func' m68k-reg='a1'/> <argument name='size' type='uint32_t' m68k-reg='d0'/> </function> <function name='objc_hashtable_set'> <argument name='table' type='struct objc_hashtable *_Nonnull' m68k-reg='a0'/> <argument name='key' type='const void *_Nonnull' m68k-reg='a1'/> <argument name='object' type='const void *_Nonnull' m68k-reg='a2'/> </function> <function name='objc_hashtable_get' return-type='void *_Nullable'> <argument name='table' type='struct objc_hashtable *_Nonnull' m68k-reg='a0'/> <argument name='key' type='const void *_Nonnull' m68k-reg='a1'/> </function> <function name='objc_hashtable_delete'> <argument name='table' type='struct objc_hashtable *_Nonnull' m68k-reg='a0'/> <argument name='key' type='const void *_Nonnull' m68k-reg='a1'/> </function> <function name='objc_hashtable_free'> <argument name='table' type='struct objc_hashtable *_Nonnull' m68k-reg='a0'/> </function> <!-- Public functions again --> <function name='objc_setTaggedPointerSecret'> <argument name='secret' type='uintptr_t' m68k-reg='d0'/> </function> <function name='objc_registerTaggedPointerClass' return-type='int'> <argument name='class' type='Class _Nonnull' m68k-reg='a0'/> </function> <function name='object_isTaggedPointer' return-type='bool'> <argument name='object' type='id _Nullable' m68k-reg='a0'/> </function> <function name='object_getTaggedPointerValue' return-type='uintptr_t'> <argument name='object' type='id _Nonnull' m68k-reg='a0'/> </function> <function name='objc_createTaggedPointer' return-type='id _Nullable'> <argument name='class' type='int' m68k-reg='d0'/> <argument name='value' type='uintptr_t' m68k-reg='d1'/> </function> </amiga-library> |
Deleted src/runtime/amigaos3.sfd version [7f54fc7db5].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/runtime/arc.m from [7f174d7d34] to [262fd1b7bb].
1 | /* | < < | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "ObjFWRT.h" #import "private.h" #ifdef OF_HAVE_THREADS # import "OFPlainMutex.h" #endif struct WeakRef { id **locations; size_t count; }; static struct objc_hashtable *hashtable; #ifdef OF_HAVE_THREADS static OFSpinlock spinlock; #endif static uint32_t hash(const void *object) { return (uint32_t)(uintptr_t)object; } static bool equal(const void *object1, const void *object2) { return (object1 == object2); } OF_CONSTRUCTOR() { hashtable = objc_hashtable_new(hash, equal, 2); #ifdef OF_HAVE_THREADS if (OFSpinlockNew(&spinlock) != 0) OBJC_ERROR("Failed to create spinlock!"); #endif } id objc_retain(id object) { return [object retain]; |
︙ | ︙ | |||
115 116 117 118 119 120 121 | return value; } id objc_storeWeak(id *object, id value) { | | | | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | return value; } id objc_storeWeak(id *object, id value) { struct WeakRef *old; #ifdef OF_HAVE_THREADS if (OFSpinlockLock(&spinlock) != 0) OBJC_ERROR("Failed to lock spinlock!"); #endif if (*object != nil && (old = objc_hashtable_get(hashtable, *object)) != NULL) { for (size_t i = 0; i < old->count; i++) { if (old->locations[i] == object) { if (--old->count == 0) { |
︙ | ︙ | |||
153 154 155 156 157 158 159 | break; } } } if (value != nil && class_respondsToSelector(object_getClass(value), @selector(allowsWeakReference)) && [value allowsWeakReference]) { | | | | | | | | | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | break; } } } if (value != nil && class_respondsToSelector(object_getClass(value), @selector(allowsWeakReference)) && [value allowsWeakReference]) { struct WeakRef *ref = objc_hashtable_get(hashtable, value); if (ref == NULL) { if ((ref = calloc(1, sizeof(*ref))) == NULL) OBJC_ERROR("Not enough memory to allocate weak " "reference!"); objc_hashtable_set(hashtable, value, ref); } if ((ref->locations = realloc(ref->locations, (ref->count + 1) * sizeof(id *))) == NULL) OBJC_ERROR("Not enough memory to allocate weak " "reference!"); ref->locations[ref->count++] = object; } else value = nil; *object = value; #ifdef OF_HAVE_THREADS if (OFSpinlockUnlock(&spinlock) != 0) OBJC_ERROR("Failed to unlock spinlock!"); #endif return value; } id objc_loadWeakRetained(id *object) { id value = nil; struct WeakRef *ref; #ifdef OF_HAVE_THREADS if (OFSpinlockLock(&spinlock) != 0) OBJC_ERROR("Failed to lock spinlock!"); #endif if (*object != nil && (ref = objc_hashtable_get(hashtable, *object)) != NULL) value = *object; #ifdef OF_HAVE_THREADS if (OFSpinlockUnlock(&spinlock) != 0) OBJC_ERROR("Failed to unlock spinlock!"); #endif if (class_respondsToSelector(object_getClass(value), @selector(retainWeakReference)) && [value retainWeakReference]) return value; return nil; |
︙ | ︙ | |||
237 238 239 240 241 242 243 | { objc_release(objc_initWeak(dest, objc_loadWeakRetained(src))); } void objc_moveWeak(id *dest, id *src) { | | | | | | | | | | | | | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 | { objc_release(objc_initWeak(dest, objc_loadWeakRetained(src))); } void objc_moveWeak(id *dest, id *src) { struct WeakRef *ref; #ifdef OF_HAVE_THREADS if (OFSpinlockLock(&spinlock) != 0) OBJC_ERROR("Failed to lock spinlock!"); #endif if (*src != nil && (ref = objc_hashtable_get(hashtable, *src)) != NULL) { for (size_t i = 0; i < ref->count; i++) { if (ref->locations[i] == src) { ref->locations[i] = dest; break; } } } *dest = *src; *src = nil; #ifdef OF_HAVE_THREADS if (OFSpinlockUnlock(&spinlock) != 0) OBJC_ERROR("Failed to unlock spinlock!"); #endif } void objc_zeroWeakReferences(id value) { struct WeakRef *ref; #ifdef OF_HAVE_THREADS if (OFSpinlockLock(&spinlock) != 0) OBJC_ERROR("Failed to lock spinlock!"); #endif if ((ref = objc_hashtable_get(hashtable, value)) != NULL) { for (size_t i = 0; i < ref->count; i++) *ref->locations[i] = nil; objc_hashtable_delete(hashtable, value); free(ref->locations); free(ref); } #ifdef OF_HAVE_THREADS if (OFSpinlockUnlock(&spinlock) != 0) OBJC_ERROR("Failed to unlock spinlock!"); #endif } |
Modified src/runtime/autorelease.m from [e5ceb906d0] to [44274c4d6f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
25 26 27 28 29 30 31 | # import "private.h" #else # import <objc/runtime.h> #endif #import "macros.h" #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) | | > > > > > | | < | > | | | | | | | > | > | | | < | > | | > | > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | # import "private.h" #else # import <objc/runtime.h> #endif #import "macros.h" #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) # import "OFTLSKey.h" #endif #ifndef OF_OBJFW_RUNTIME @interface DummyObject - (void)release; @end #endif #ifndef OBJC_ERROR /* This is also used with old Apple runtimes that lack autorelease pools. */ # define OBJC_ERROR(...) abort() #endif #if defined(OF_HAVE_COMPILER_TLS) static thread_local id *objects = NULL; static thread_local uintptr_t count = 0; static thread_local uintptr_t size = 0; #elif defined(OF_HAVE_THREADS) static OFTLSKey objectsKey, countKey, sizeKey; #else static id *objects = NULL; static uintptr_t count = 0; static uintptr_t size = 0; #endif #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) OF_CONSTRUCTOR() { if (OFTLSKeyNew(&objectsKey) != 0 || OFTLSKeyNew(&countKey) != 0 || OFTLSKeyNew(&sizeKey) != 0) OBJC_ERROR("Failed to create TLS keys!"); } #endif void * objc_autoreleasePoolPush() { #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) uintptr_t count = (uintptr_t)OFTLSKeyGet(countKey); #endif return (void *)count; } void objc_autoreleasePoolPop(void *pool) { #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) id *objects = OFTLSKeyGet(objectsKey); uintptr_t count = (uintptr_t)OFTLSKeyGet(countKey); #endif uintptr_t idx = (uintptr_t)pool; bool freeMem = false; if (idx == (uintptr_t)-1) { idx++; freeMem = true; } for (uintptr_t i = idx; i < count; i++) { [objects[i] release]; #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) objects = OFTLSKeyGet(objectsKey); count = (uintptr_t)OFTLSKeyGet(countKey); #endif } count = idx; if (freeMem) { free(objects); objects = NULL; #if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS) size = 0; #else if (OFTLSKeySet(objectsKey, objects) != 0 || OFTLSKeySet(sizeKey, (void *)0) != 0) OBJC_ERROR("Failed to set TLS key!"); #endif } #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) if (OFTLSKeySet(countKey, (void *)count) != 0) OBJC_ERROR("Failed to set TLS key!"); #endif } id _objc_rootAutorelease(id object) { #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) id *objects = OFTLSKeyGet(objectsKey); uintptr_t count = (uintptr_t)OFTLSKeyGet(countKey); uintptr_t size = (uintptr_t)OFTLSKeyGet(sizeKey); #endif if (count >= size) { if (size == 0) size = 16; else size *= 2; if ((objects = realloc(objects, size * sizeof(id))) == NULL) OBJC_ERROR("Failed to resize autorelease pool!"); #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) if (OFTLSKeySet(objectsKey, objects) != 0 || OFTLSKeySet(sizeKey, (void *)size) != 0) OBJC_ERROR("Failed to set TLS key!"); #endif } objects[count++] = object; #if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS) if (OFTLSKeySet(countKey, (void *)count) != 0) OBJC_ERROR("Failed to set TLS key!"); #endif return object; } |
Modified src/runtime/category.m from [d697edeb41] to [7faaa519d3].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | registerSelectors(struct objc_category *category) { struct objc_method_list *iter; unsigned int i; for (iter = category->instanceMethods; iter != NULL; iter = iter->next) for (i = 0; i < iter->count; i++) | | | | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | registerSelectors(struct objc_category *category) { struct objc_method_list *iter; unsigned int i; for (iter = category->instanceMethods; iter != NULL; iter = iter->next) for (i = 0; i < iter->count; i++) objc_registerSelector(&iter->methods[i].selector); for (iter = category->classMethods; iter != NULL; iter = iter->next) for (i = 0; i < iter->count; i++) objc_registerSelector(&iter->methods[i].selector); } static void registerCategory(struct objc_category *category) { struct objc_category **categories; Class class = objc_classnameToClass(category->className, false); if (categoriesMap == NULL) categoriesMap = objc_hashtable_new( objc_string_hash, objc_string_equal, 2); categories = (struct objc_category **)objc_hashtable_get( categoriesMap, category->className); if (categories != NULL) { struct objc_category **newCategories; size_t i; |
︙ | ︙ | |||
68 69 70 71 72 73 74 | newCategories[i] = category; newCategories[i + 1] = NULL; objc_hashtable_set(categoriesMap, category->className, newCategories); if (class != Nil && class->info & OBJC_CLASS_INFO_SETUP) { | | | | | | | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | newCategories[i] = category; newCategories[i + 1] = NULL; objc_hashtable_set(categoriesMap, category->className, newCategories); if (class != Nil && class->info & OBJC_CLASS_INFO_SETUP) { objc_updateDTable(class); objc_updateDTable(class->isa); } return; } if ((categories = malloc(2 * sizeof(*categories))) == NULL) OBJC_ERROR("Not enough memory for category %s of class %s!\n", category->categoryName, category->className); categories[0] = category; categories[1] = NULL; objc_hashtable_set(categoriesMap, category->className, categories); if (class != Nil && class->info & OBJC_CLASS_INFO_SETUP) { objc_updateDTable(class); objc_updateDTable(class->isa); } } void objc_registerAllCategories(struct objc_symtab *symtab) { struct objc_category **categories = (struct objc_category **)symtab->defs + symtab->classDefsCount; for (size_t i = 0; i < symtab->categoryDefsCount; i++) { registerSelectors(categories[i]); registerCategory(categories[i]); } } struct objc_category ** objc_categoriesForClass(Class class) { if (categoriesMap == NULL) return NULL; return (struct objc_category **)objc_hashtable_get(categoriesMap, class->name); } void objc_unregisterAllCategories(void) { if (categoriesMap == NULL) return; for (uint32_t i = 0; i < categoriesMap->size; i++) if (categoriesMap->data[i] != NULL) free((void *)categoriesMap->data[i]->object); objc_hashtable_free(categoriesMap); categoriesMap = NULL; } |
Modified src/runtime/class.m from [0dc727f4b5] to [8d4b7cca0f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
34 35 36 37 38 39 40 | static struct objc_sparsearray *fastPath = NULL; static void registerClass(Class class) { if (classes == NULL) classes = objc_hashtable_new( | | | | | | | | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | static struct objc_sparsearray *fastPath = NULL; static void registerClass(Class class) { if (classes == NULL) classes = objc_hashtable_new( objc_string_hash, objc_string_equal, 2); objc_hashtable_set(classes, class->name, class); if (emptyDTable == NULL) emptyDTable = objc_dtable_new(); class->dTable = emptyDTable; class->isa->dTable = emptyDTable; if (strcmp(class->name, "Protocol") != 0) classesCount++; } bool class_registerAlias_np(Class class, const char *name) { objc_globalMutex_lock(); if (classes == NULL) { objc_globalMutex_unlock(); return NO; } objc_hashtable_set(classes, name, (Class)((uintptr_t)class | 1)); objc_globalMutex_unlock(); return YES; } static void registerSelectors(Class class) { struct objc_method_list *iter; unsigned int i; for (iter = class->methodList; iter != NULL; iter = iter->next) for (i = 0; i < iter->count; i++) objc_registerSelector(&iter->methods[i].selector); } Class objc_classnameToClass(const char *name, bool cache) { Class class; if (classes == NULL) return Nil; /* |
︙ | ︙ | |||
113 114 115 116 117 118 119 | if (cache && fastPath != NULL) { class = objc_sparsearray_get(fastPath, (uintptr_t)name); if (class != Nil) return class; } | | | | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | if (cache && fastPath != NULL) { class = objc_sparsearray_get(fastPath, (uintptr_t)name); if (class != Nil) return class; } objc_globalMutex_lock(); class = (Class)((uintptr_t)objc_hashtable_get(classes, name) & ~1); if (cache && fastPath == NULL && --lookupsUntilFastPath == 0) fastPath = objc_sparsearray_new(sizeof(uintptr_t)); if (cache && fastPath != NULL) objc_sparsearray_set(fastPath, (uintptr_t)name, class); objc_globalMutex_unlock(); return class; } static void callSelector(Class class, SEL selector) { |
︙ | ︙ | |||
178 179 180 181 182 183 184 | callSelector(class, loadSel); class->info |= OBJC_CLASS_INFO_LOADED; } void | | | | | | | | | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | callSelector(class, loadSel); class->info |= OBJC_CLASS_INFO_LOADED; } void objc_updateDTable(Class class) { struct objc_category **categories; if (!(class->info & OBJC_CLASS_INFO_DTABLE)) return; if (class->dTable == emptyDTable) class->dTable = objc_dtable_new(); if (class->superclass != Nil) objc_dtable_copy(class->dTable, class->superclass->dTable); for (struct objc_method_list *methodList = class->methodList; methodList != NULL; methodList = methodList->next) for (unsigned int i = 0; i < methodList->count; i++) objc_dtable_set(class->dTable, (uint32_t)methodList->methods[i].selector.UID, methodList->methods[i].implementation); if ((categories = objc_categoriesForClass(class)) != NULL) { for (unsigned int i = 0; categories[i] != NULL; i++) { struct objc_method_list *methodList = (class->info & OBJC_CLASS_INFO_CLASS ? categories[i]->instanceMethods : categories[i]->classMethods); for (; methodList != NULL; methodList = methodList->next) for (unsigned int j = 0; j < methodList->count; j++) objc_dtable_set(class->dTable, (uint32_t)methodList->methods[j] .selector.UID, methodList->methods[j] .implementation); } } if (class->subclassList != NULL) for (Class *iter = class->subclassList; *iter != NULL; iter++) objc_updateDTable(*iter); } static void addSubclass(Class class) { size_t i; |
︙ | ︙ | |||
280 281 282 283 284 285 286 | } } else for (unsigned int i = 0; i < class->ivars->count; i++) *class->ivarOffsets[i] = class->ivars->ivars[i].offset; } static void | | | | | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | } } else for (unsigned int i = 0; i < class->ivars->count; i++) *class->ivarOffsets[i] = class->ivars->ivars[i].offset; } static void setUpClass(Class class) { const char *superclassName; if (class->info & OBJC_CLASS_INFO_SETUP) return; superclassName = (const char *)class->superclass; if (superclassName != NULL) { Class super = objc_classnameToClass(superclassName, false); Class rootClass; if (super == Nil) return; setUpClass(super); if (!(super->info & OBJC_CLASS_INFO_SETUP)) return; /* * GCC sets class->isa->isa to the name of the root class, * while Clang just sets it to Nil. Therefore always calculate |
︙ | ︙ | |||
339 340 341 342 343 344 345 346 347 348 | if (class->info & OBJC_CLASS_INFO_INITIALIZED) return; if (class->superclass) initializeClass(class->superclass); class->info |= OBJC_CLASS_INFO_DTABLE; class->isa->info |= OBJC_CLASS_INFO_DTABLE; | > > > > > > > | | | 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 | if (class->info & OBJC_CLASS_INFO_INITIALIZED) return; if (class->superclass) initializeClass(class->superclass); /* * Avoid double-initialization: One of the superclasses' +[initialize] * might have called this class and hence it already got initialized. */ if (class->info & OBJC_CLASS_INFO_INITIALIZED) return; class->info |= OBJC_CLASS_INFO_DTABLE; class->isa->info |= OBJC_CLASS_INFO_DTABLE; objc_updateDTable(class); objc_updateDTable(class->isa); /* * Set it first to prevent calling it recursively due to message sends * in the initialize method */ class->info |= OBJC_CLASS_INFO_INITIALIZED; class->isa->info |= OBJC_CLASS_INFO_INITIALIZED; |
︙ | ︙ | |||
366 367 368 369 370 371 372 | objc_msg_lookup(class, initializeSel); initialize(class, initializeSel); } } void | | | | | | | | | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 | objc_msg_lookup(class, initializeSel); initialize(class, initializeSel); } } void objc_initializeClass(Class class) { if (class->info & OBJC_CLASS_INFO_INITIALIZED) return; objc_globalMutex_lock(); /* * It's possible that two threads try to initialize a class at the same * time. Make sure that the thread which held the lock did not already * initialize it. */ if (class->info & OBJC_CLASS_INFO_INITIALIZED) { objc_globalMutex_unlock(); return; } setUpClass(class); if (!(class->info & OBJC_CLASS_INFO_SETUP)) { objc_globalMutex_unlock(); return; } initializeClass(class); objc_globalMutex_unlock(); } static void processLoadQueue() { for (size_t i = 0; i < loadQueueCount; i++) { setUpClass(loadQueue[i]); if (loadQueue[i]->info & OBJC_CLASS_INFO_SETUP) { callLoad(loadQueue[i]); loadQueueCount--; if (loadQueueCount == 0) { |
︙ | ︙ | |||
424 425 426 427 428 429 430 | if (loadQueue == NULL) OBJC_ERROR("Not enough memory for load queue!"); } } } void | | | | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | if (loadQueue == NULL) OBJC_ERROR("Not enough memory for load queue!"); } } } void objc_registerAllClasses(struct objc_symtab *symtab) { for (uint16_t i = 0; i < symtab->classDefsCount; i++) { Class class = (Class)symtab->defs[i]; registerClass(class); registerSelectors(class); registerSelectors(class->isa); } for (uint16_t i = 0; i < symtab->classDefsCount; i++) { Class class = (Class)symtab->defs[i]; if (hasLoad(class)) { setUpClass(class); if (class->info & OBJC_CLASS_INFO_SETUP) callLoad(class); else { loadQueue = realloc(loadQueue, sizeof(Class) * (loadQueueCount + 1)); |
︙ | ︙ | |||
465 466 467 468 469 470 471 | Class objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes) { struct objc_class *class, *metaclass; Class iter, rootclass = Nil; | < < < | | > > > > > > | | | | | | | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 | Class objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes) { struct objc_class *class, *metaclass; Class iter, rootclass = Nil; if ((class = calloc(1, sizeof(*class))) == NULL || (metaclass = calloc(1, sizeof(*class))) == NULL) OBJC_ERROR("Not enough memory to allocate class pair for class " "%s!", name); class->isa = metaclass; class->superclass = superclass; class->name = name; class->info = OBJC_CLASS_INFO_CLASS; class->instanceSize = (superclass != Nil ? superclass->instanceSize : 0); if (extraBytes > LONG_MAX || LONG_MAX - class->instanceSize < (long)extraBytes) OBJC_ERROR("extraBytes too large!"); class->instanceSize += (long)extraBytes; for (iter = superclass; iter != Nil; iter = iter->superclass) rootclass = iter; metaclass->isa = (rootclass != Nil ? rootclass->isa : class); metaclass->superclass = (superclass != Nil ? superclass->isa : Nil); metaclass->name = name; metaclass->info = OBJC_CLASS_INFO_CLASS; metaclass->instanceSize = (superclass != Nil ? superclass->isa->instanceSize : 0) + (long)extraBytes; return class; } void objc_registerClassPair(Class class) { objc_globalMutex_lock(); registerClass(class); if (class->superclass != Nil) { addSubclass(class); addSubclass(class->isa); } class->info |= OBJC_CLASS_INFO_SETUP; class->isa->info |= OBJC_CLASS_INFO_SETUP; if (hasLoad(class)) callLoad(class); else class->info |= OBJC_CLASS_INFO_LOADED; processLoadQueue(); objc_globalMutex_unlock(); } Class objc_lookUpClass(const char *name) { Class class; if ((class = objc_classnameToClass(name, true)) == NULL) return Nil; if (class->info & OBJC_CLASS_INFO_SETUP) return class; objc_globalMutex_lock(); setUpClass(class); objc_globalMutex_unlock(); if (!(class->info & OBJC_CLASS_INFO_SETUP)) return Nil; return class; } |
︙ | ︙ | |||
574 575 576 577 578 579 580 | return objc_getRequiredClass(name); } unsigned int objc_getClassList(Class *buffer, unsigned int count) { unsigned int j; | | | | | | > | | 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 | return objc_getRequiredClass(name); } unsigned int objc_getClassList(Class *buffer, unsigned int count) { unsigned int j; objc_globalMutex_lock(); if (buffer == NULL) return classesCount; if (classesCount < count) count = classesCount; j = 0; for (uint32_t i = 0; i < classes->size; i++) { void *class; if (j >= count) { objc_globalMutex_unlock(); return j; } if (classes->data[i] == NULL) continue; if (strcmp(classes->data[i]->key, "Protocol") == 0) continue; class = (Class)classes->data[i]->object; if (class == Nil || (uintptr_t)class & 1) continue; buffer[j++] = class; } objc_globalMutex_unlock(); return j; } Class * objc_copyClassList(unsigned int *length) { Class *ret; unsigned int count; objc_globalMutex_lock(); if ((ret = malloc((classesCount + 1) * sizeof(Class))) == NULL) OBJC_ERROR("Failed to allocate memory for class list!"); count = objc_getClassList(ret, classesCount); if (count != classesCount) OBJC_ERROR("Fatal internal inconsistency!"); ret[count] = Nil; if (length != NULL) *length = count; objc_globalMutex_unlock(); return ret; } bool class_isMetaClass(Class class) { |
︙ | ︙ | |||
717 718 719 720 721 722 723 | } static struct objc_method * getMethod(Class class, SEL selector) { struct objc_category **categories; | | | 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 | } static struct objc_method * getMethod(Class class, SEL selector) { struct objc_category **categories; if ((categories = objc_categoriesForClass(class)) != NULL) { for (; *categories != NULL; categories++) { struct objc_method_list *methodList = (class->info & OBJC_CLASS_INFO_METACLASS ? (*categories)->classMethods : (*categories)->instanceMethods); for (; methodList != NULL; |
︙ | ︙ | |||
751 752 753 754 755 756 757 | static void addMethod(Class class, SEL selector, IMP implementation, const char *typeEncoding) { struct objc_method_list *methodList; | | | | | | | | | | | | 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 | static void addMethod(Class class, SEL selector, IMP implementation, const char *typeEncoding) { struct objc_method_list *methodList; /* FIXME: We need a way to free this at objc_deinit() */ if ((methodList = malloc(sizeof(*methodList))) == NULL) OBJC_ERROR("Not enough memory to replace method!"); methodList->next = class->methodList; methodList->count = 1; methodList->methods[0].selector.UID = selector->UID; methodList->methods[0].selector.typeEncoding = typeEncoding; methodList->methods[0].implementation = implementation; class->methodList = methodList; objc_updateDTable(class); } Method class_getInstanceMethod(Class class, SEL selector) { Method method; Class superclass; if (class == Nil) return NULL; objc_globalMutex_lock(); if ((method = getMethod(class, selector)) != NULL) { objc_globalMutex_unlock(); return method; } superclass = class->superclass; objc_globalMutex_unlock(); if (superclass != Nil) return class_getInstanceMethod(superclass, selector); return NULL; } bool class_addMethod(Class class, SEL selector, IMP implementation, const char *typeEncoding) { bool ret; objc_globalMutex_lock(); if (getMethod(class, selector) == NULL) { addMethod(class, selector, implementation, typeEncoding); ret = true; } else ret = false; objc_globalMutex_unlock(); return ret; } IMP class_replaceMethod(Class class, SEL selector, IMP implementation, const char *typeEncoding) { struct objc_method *method; IMP oldImplementation; objc_globalMutex_lock(); if ((method = getMethod(class, selector)) != NULL) { oldImplementation = method->implementation; method->implementation = implementation; objc_updateDTable(class); } else { oldImplementation = NULL; addMethod(class, selector, implementation, typeEncoding); } objc_globalMutex_unlock(); return oldImplementation; } Class object_getClass(id object_) { |
︙ | ︙ | |||
905 906 907 908 909 910 911 | } if (class->subclassList != NULL) { free(class->subclassList); class->subclassList = NULL; } | | | | | > > | > > | | | | > | 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 | } if (class->subclassList != NULL) { free(class->subclassList); class->subclassList = NULL; } if (class->dTable != NULL && class->dTable != emptyDTable) objc_dtable_free(class->dTable); class->dTable = NULL; if ((class->info & OBJC_CLASS_INFO_SETUP) && class->superclass != Nil) class->superclass = (Class)class->superclass->name; class->info &= ~OBJC_CLASS_INFO_SETUP; } void objc_unregisterClass(Class class) { static SEL unloadSel = NULL; objc_globalMutex_lock(); if (unloadSel == NULL) unloadSel = sel_registerName("unload"); while (class->subclassList != NULL && class->subclassList[0] != Nil) objc_unregisterClass(class->subclassList[0]); if (class->info & OBJC_CLASS_INFO_LOADED) callSelector(class, unloadSel); objc_hashtable_delete(classes, class->name); if (strcmp(class_getName(class), "Protocol") != 0) classesCount--; unregisterClass(class); unregisterClass(class->isa); objc_globalMutex_unlock(); } void objc_unregisterAllClasses(void) { if (classes == NULL) return; for (uint32_t i = 0; i < classes->size; i++) { if (classes->data[i] != NULL && classes->data[i] != &objc_deletedBucket) { void *class = (Class)classes->data[i]->object; if (class == Nil || (uintptr_t)class & 1) continue; objc_unregisterClass(class); /* * The table might have been resized, so go back to the * start again. * * Due to the i++ in the for loop, we need to set it to * UINT32_MAX so that it will get increased at the end * of the loop and thus become 0. */ i = UINT32_MAX; } } if (classesCount != 0) OBJC_ERROR("Fatal internal inconsistency!"); if (emptyDTable != NULL) { objc_dtable_free(emptyDTable); emptyDTable = NULL; } objc_sparsearray_free(fastPath); fastPath = NULL; objc_hashtable_free(classes); classes = NULL; } |
Modified src/runtime/dtable.m from [6362d17715] to [f0602aa5e2].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | static struct objc_dtable_level3 *emptyLevel3 = NULL; #endif static void init(void) { if ((emptyLevel2 = malloc(sizeof(*emptyLevel2))) == NULL) | | | | | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | static struct objc_dtable_level3 *emptyLevel3 = NULL; #endif static void init(void) { if ((emptyLevel2 = malloc(sizeof(*emptyLevel2))) == NULL) OBJC_ERROR("Not enough memory to allocate dispatch table!"); #ifdef OF_SELUID24 if ((emptyLevel3 = malloc(sizeof(*emptyLevel3))) == NULL) OBJC_ERROR("Not enough memory to allocate dispatch table!"); #endif #ifdef OF_SELUID24 for (uint_fast16_t i = 0; i < 256; i++) { emptyLevel2->buckets[i] = emptyLevel3; emptyLevel3->buckets[i] = (IMP)0; } #else for (uint_fast16_t i = 0; i < 256; i++) emptyLevel2->buckets[i] = (IMP)0; #endif } struct objc_dtable * objc_dtable_new(void) { struct objc_dtable *dTable; #ifdef OF_SELUID24 if (emptyLevel2 == NULL || emptyLevel3 == NULL) init(); #else if (emptyLevel2 == NULL) init(); #endif if ((dTable = malloc(sizeof(*dTable))) == NULL) OBJC_ERROR("Not enough memory to allocate dispatch table!"); for (uint_fast16_t i = 0; i < 256; i++) dTable->buckets[i] = emptyLevel2; return dTable; } void objc_dtable_copy(struct objc_dtable *dest, struct objc_dtable *src) { for (uint_fast16_t i = 0; i < 256; i++) { if (src->buckets[i] == emptyLevel2) |
︙ | ︙ | |||
111 112 113 114 115 116 117 | objc_dtable_set(dest, idx, implementation); } #endif } } void | | | | > | | | > | | | | | | | | | | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | objc_dtable_set(dest, idx, implementation); } #endif } } void objc_dtable_set(struct objc_dtable *dTable, uint32_t idx, IMP implementation) { #ifdef OF_SELUID24 uint8_t i = idx >> 16; uint8_t j = idx >> 8; uint8_t k = idx; #else uint8_t i = idx >> 8; uint8_t j = idx; #endif if (dTable->buckets[i] == emptyLevel2) { struct objc_dtable_level2 *level2 = malloc(sizeof(*level2)); if (level2 == NULL) OBJC_ERROR("Not enough memory to insert into " "dispatch table!"); for (uint_fast16_t l = 0; l < 256; l++) #ifdef OF_SELUID24 level2->buckets[l] = emptyLevel3; #else level2->buckets[l] = (IMP)0; #endif dTable->buckets[i] = level2; } #ifdef OF_SELUID24 if (dTable->buckets[i]->buckets[j] == emptyLevel3) { struct objc_dtable_level3 *level3 = malloc(sizeof(*level3)); if (level3 == NULL) OBJC_ERROR("Not enough memory to insert into " "dispatch table!"); for (uint_fast16_t l = 0; l < 256; l++) level3->buckets[l] = (IMP)0; dTable->buckets[i]->buckets[j] = level3; } dTable->buckets[i]->buckets[j]->buckets[k] = implementation; #else dTable->buckets[i]->buckets[j] = implementation; #endif } void objc_dtable_free(struct objc_dtable *dTable) { for (uint_fast16_t i = 0; i < 256; i++) { if (dTable->buckets[i] == emptyLevel2) continue; #ifdef OF_SELUID24 for (uint_fast16_t j = 0; j < 256; j++) if (dTable->buckets[i]->buckets[j] != emptyLevel3) free(dTable->buckets[i]->buckets[j]); #endif free(dTable->buckets[i]); } free(dTable); } void objc_dtable_cleanup(void) { if (emptyLevel2 != NULL) free(emptyLevel2); |
︙ | ︙ |
Modified src/runtime/exception.m from [ff0a7a161b] to [ba2a43d17f].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 | #include <string.h> #import "ObjFWRT.h" #import "private.h" #import "macros.h" #ifdef OF_HAVE_THREADS | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include <string.h> #import "ObjFWRT.h" #import "private.h" #import "macros.h" #ifdef OF_HAVE_THREADS # include "OFPlainMutex.h" #endif #ifdef HAVE_SEH_EXCEPTIONS # include <windows.h> #endif #if defined(HAVE_DWARF_EXCEPTIONS) |
︙ | ︙ | |||
67 68 69 70 71 72 73 | # define CALL_PERSONALITY(func) func(state, ex, ctx) #endif #define GNUCOBJC_EXCEPTION_CLASS UINT64_C(0x474E55434F424A43) /* GNUCOBJC */ #define GNUCCXX0_EXCEPTION_CLASS UINT64_C(0x474E5543432B2B00) /* GNUCC++\0 */ #define CLNGCXX0_EXCEPTION_CLASS UINT64_C(0x434C4E47432B2B00) /* CLNGC++\0 */ | | > | | | | > > | | | | | | | | | | | | | | | | | > > | | > | 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | # define CALL_PERSONALITY(func) func(state, ex, ctx) #endif #define GNUCOBJC_EXCEPTION_CLASS UINT64_C(0x474E55434F424A43) /* GNUCOBJC */ #define GNUCCXX0_EXCEPTION_CLASS UINT64_C(0x474E5543432B2B00) /* GNUCC++\0 */ #define CLNGCXX0_EXCEPTION_CLASS UINT64_C(0x434C4E47432B2B00) /* CLNGC++\0 */ #define numEmergencyExceptions 4 enum { _UA_SEARCH_PHASE = 0x01, _UA_CLEANUP_PHASE = 0x02, _UA_HANDLER_FRAME = 0x04, _UA_FORCE_UNWIND = 0x08 }; enum { DW_EH_PE_absptr = 0x00, DW_EH_PE_uleb128 = 0x01, DW_EH_PE_udata2 = 0x02, DW_EH_PE_udata4 = 0x03, DW_EH_PE_udata8 = 0x04, DW_EH_PE_signed = 0x08, DW_EH_PE_sleb128 = (DW_EH_PE_signed | DW_EH_PE_uleb128), DW_EH_PE_sdata2 = (DW_EH_PE_signed | DW_EH_PE_udata2), DW_EH_PE_sdata4 = (DW_EH_PE_signed | DW_EH_PE_udata4), DW_EH_PE_sdata8 = (DW_EH_PE_signed | DW_EH_PE_udata8), DW_EH_PE_pcrel = 0x10, DW_EH_PE_textrel = 0x20, DW_EH_PE_datarel = 0x30, DW_EH_PE_funcrel = 0x40, DW_EH_PE_aligned = 0x50, DW_EH_PE_indirect = 0x80, DW_EH_PE_omit = 0xFF }; enum { CLEANUP_FOUND = 0x01, HANDLER_FOUND = 0x02 }; struct _Unwind_Context; typedef enum { _URC_OK = 0, _URC_FATAL_PHASE1_ERROR = 3, _URC_END_OF_STACK = 5, |
︙ | ︙ | |||
156 157 158 159 160 161 162 | id object; #ifndef HAVE_ARM_EHABI_EXCEPTIONS uintptr_t landingpad; intptr_t filter; #endif }; | | | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | id object; #ifndef HAVE_ARM_EHABI_EXCEPTIONS uintptr_t landingpad; intptr_t filter; #endif }; struct LSDA { uintptr_t regionStart, landingpadsStart; uint8_t typesTableEnc; const uint8_t *typesTable; uintptr_t typesTableBase; uint8_t callsitesEnc; const uint8_t *callsites, *actionTable; }; |
︙ | ︙ | |||
237 238 239 240 241 242 243 | #ifdef HAVE_SEH_EXCEPTIONS extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *, PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code (*)(int, int, uint64_t, struct _Unwind_Exception *, struct _Unwind_Context *)); #endif | | | | | | | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | #ifdef HAVE_SEH_EXCEPTIONS extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, void *, PCONTEXT, PDISPATCHER_CONTEXT, _Unwind_Reason_Code (*)(int, int, uint64_t, struct _Unwind_Exception *, struct _Unwind_Context *)); #endif static objc_uncaught_exception_handler uncaughtExceptionHandler; static struct objc_exception emergencyExceptions[numEmergencyExceptions]; #ifdef OF_HAVE_THREADS static OFSpinlock emergencyExceptionsSpinlock; OF_CONSTRUCTOR() { if (OFSpinlockNew(&emergencyExceptionsSpinlock) != 0) OBJC_ERROR("Failed to create spinlock!"); } #endif static uint64_t readULEB128(const uint8_t **ptr) { uint64_t value = 0; |
︙ | ︙ | |||
306 307 308 309 310 311 312 | #endif #ifdef HAVE__UNWIND_GETTEXTRELBASE case DW_EH_PE_textrel: return _Unwind_GetTextRelBase(ctx); #endif } | | | | > > | > > > > | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | #endif #ifdef HAVE__UNWIND_GETTEXTRELBASE case DW_EH_PE_textrel: return _Unwind_GetTextRelBase(ctx); #endif } OBJC_ERROR("Unknown encoding!"); } static size_t sizeForEncoding(uint8_t enc) { if (enc == DW_EH_PE_omit) return 0; switch (enc & 0x07) { case DW_EH_PE_absptr: return sizeof(void *); case DW_EH_PE_udata2: return 2; case DW_EH_PE_udata4: return 4; case DW_EH_PE_udata8: return 8; } OBJC_ERROR("Unknown encoding!"); } static uint64_t readValue(uint8_t enc, const uint8_t **ptr) { uint64_t value; if (enc == DW_EH_PE_aligned) { const uintptr_t *aligned = (const uintptr_t *) OFRoundUpToPowerOf2(sizeof(void *), (uintptr_t)*ptr); *ptr = (const uint8_t *)(aligned + 1); return *aligned; } #define READ(type) \ { \ type tmp; \ memcpy(&tmp, *ptr, sizeof(type)); \ value = tmp; \ *ptr += sizeForEncoding(enc); \ |
︙ | ︙ | |||
367 368 369 370 371 372 373 | case DW_EH_PE_sdata2: READ(int16_t) case DW_EH_PE_sdata4: READ(int32_t) case DW_EH_PE_sdata8: READ(int64_t) default: | | | | | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 | case DW_EH_PE_sdata2: READ(int16_t) case DW_EH_PE_sdata4: READ(int32_t) case DW_EH_PE_sdata8: READ(int64_t) default: OBJC_ERROR("Unknown encoding!"); } #undef READ return value; } #ifndef HAVE_ARM_EHABI_EXCEPTIONS static uint64_t resolveValue(uint64_t value, uint8_t enc, const uint8_t *start, uint64_t base) { if (value == 0 || enc == DW_EH_PE_aligned) return value; value += ((enc & 0x70) == DW_EH_PE_pcrel ? (uintptr_t)start : base); if (enc & DW_EH_PE_indirect) value = *(uintptr_t *)(uintptr_t)value; return value; } #endif static void readLSDA(struct _Unwind_Context *ctx, const uint8_t *ptr, struct LSDA *LSDA) { uint8_t landingpadsStartEnc; uintptr_t callsitesSize; LSDA->regionStart = _Unwind_GetRegionStart(ctx); LSDA->landingpadsStart = LSDA->regionStart; LSDA->typesTable = NULL; |
︙ | ︙ | |||
419 420 421 422 423 424 425 | callsitesSize = (uintptr_t)readULEB128(&ptr); LSDA->callsites = ptr; LSDA->actionTable = LSDA->callsites + callsitesSize; } static bool | | | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | callsitesSize = (uintptr_t)readULEB128(&ptr); LSDA->callsites = ptr; LSDA->actionTable = LSDA->callsites + callsitesSize; } static bool findCallsite(struct _Unwind_Context *ctx, struct LSDA *LSDA, uintptr_t *landingpad, const uint8_t **actionRecords) { uintptr_t IP = _Unwind_GetIP(ctx); const uint8_t *ptr = LSDA->callsites; *landingpad = 0; *actionRecords = NULL; |
︙ | ︙ | |||
496 497 498 499 500 501 502 | if (iter == class) return true; return false; } static uint8_t | | | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 | if (iter == class) return true; return false; } static uint8_t findActionRecord(const uint8_t *actionRecords, struct LSDA *LSDA, int actions, bool foreign, struct objc_exception *e, intptr_t *filterPtr) { const uint8_t *ptr; intptr_t filter, displacement; do { ptr = actionRecords; |
︙ | ︙ | |||
556 557 558 559 560 561 562 | if (classMatches(class, e->object)) { *filterPtr = filter; return HANDLER_FOUND; } } else if (filter == 0) return CLEANUP_FOUND; else if (filter < 0) | | | 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | if (classMatches(class, e->object)) { *filterPtr = filter; return HANDLER_FOUND; } } else if (filter == 0) return CLEANUP_FOUND; else if (filter < 0) OBJC_ERROR("Invalid filter!"); } while (displacement != 0); return 0; } #ifdef HAVE_SEH_EXCEPTIONS static |
︙ | ︙ | |||
592 593 594 595 596 597 598 | } _Unwind_SetGR(ctx, 12, (uintptr_t)ex); #endif struct objc_exception *e = (struct objc_exception *)ex; bool foreign = (exClass != GNUCOBJC_EXCEPTION_CLASS); const uint8_t *LSDAAddr, *actionRecords; | | | 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 | } _Unwind_SetGR(ctx, 12, (uintptr_t)ex); #endif struct objc_exception *e = (struct objc_exception *)ex; bool foreign = (exClass != GNUCOBJC_EXCEPTION_CLASS); const uint8_t *LSDAAddr, *actionRecords; struct LSDA LSDA; uintptr_t landingpad = 0; uint8_t found = 0; intptr_t filter = 0; if (foreign) { switch (exClass) { #ifdef CXX_PERSONALITY |
︙ | ︙ | |||
688 689 690 691 692 693 694 | (uintptr_t)ex); _Unwind_SetGR(ctx, __builtin_eh_return_data_regno(1), filter); _Unwind_SetIP(ctx, landingpad); return _URC_INSTALL_CONTEXT; } | > | | | | | | | | | | | | | | | | 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 | (uintptr_t)ex); _Unwind_SetGR(ctx, __builtin_eh_return_data_regno(1), filter); _Unwind_SetIP(ctx, landingpad); return _URC_INSTALL_CONTEXT; } OBJC_ERROR( "Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE in actions!"); } static void cleanup(_Unwind_Reason_Code reason, struct _Unwind_Exception *ex) { free(ex); } static void emergencyExceptionCleanup(_Unwind_Reason_Code reason, struct _Unwind_Exception *ex) { #ifdef OF_HAVE_THREADS if (OFSpinlockLock(&emergencyExceptionsSpinlock) != 0) OBJC_ERROR("Failed to lock spinlock!"); #endif ex->class = 0; #ifdef OF_HAVE_THREADS if (OFSpinlockUnlock(&emergencyExceptionsSpinlock) != 0) OBJC_ERROR("Failed to unlock spinlock!"); #endif } void objc_exception_throw(id object) { struct objc_exception *e = calloc(1, sizeof(*e)); bool emergency = false; if (e == NULL) { #ifdef OF_HAVE_THREADS if (OFSpinlockLock(&emergencyExceptionsSpinlock) != 0) OBJC_ERROR("Failed to lock spinlock!"); #endif for (uint_fast8_t i = 0; i < numEmergencyExceptions; i++) { if (emergencyExceptions[i].exception.class == 0) { e = &emergencyExceptions[i]; e->exception.class = GNUCOBJC_EXCEPTION_CLASS; emergency = true; break; } } #ifdef OF_HAVE_THREADS if (OFSpinlockUnlock(&emergencyExceptionsSpinlock) != 0) OBJC_ERROR("Failed to lock spinlock!"); #endif } if (e == NULL) OBJC_ERROR("Not enough memory to allocate exception!"); e->exception.class = GNUCOBJC_EXCEPTION_CLASS; e->exception.cleanup = (emergency ? emergencyExceptionCleanup : cleanup); e->object = object; _Unwind_RaiseException(&e->exception); if (uncaughtExceptionHandler != NULL) uncaughtExceptionHandler(object); OBJC_ERROR("_Unwind_RaiseException() returned!"); } objc_uncaught_exception_handler objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler handler) { objc_uncaught_exception_handler old = uncaughtExceptionHandler; uncaughtExceptionHandler = handler; return old; } #ifdef HAVE_SEH_EXCEPTIONS typedef EXCEPTION_DISPOSITION (*seh_personality_fn)(PEXCEPTION_RECORD, void *, |
︙ | ︙ |
Modified src/runtime/hashtable.m from [f92943fe11] to [4617c1e6d6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | #include <stdio.h> #include <stdlib.h> #include <string.h> #import "ObjFWRT.h" #import "private.h" | | | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #include <stdio.h> #include <stdlib.h> #include <string.h> #import "ObjFWRT.h" #import "private.h" struct objc_hashtable_bucket objc_deletedBucket; uint32_t objc_string_hash(const void *str_) { const char *str = str_; uint32_t hash = 0; while (*str != 0) { hash += *str; hash += (hash << 10); hash ^= (hash >> 6); str++; } hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15); return hash; } bool objc_string_equal(const void *ptr1, const void *ptr2) { return (strcmp(ptr1, ptr2) == 0); } struct objc_hashtable * objc_hashtable_new(uint32_t (*hash)(const void *), bool (*equal)(const void *, const void *), uint32_t size) |
︙ | ︙ | |||
101 102 103 104 105 106 107 | return; if ((newData = calloc(newSize, sizeof(*newData))) == NULL) OBJC_ERROR("Not enough memory to resize hash table!"); for (uint32_t i = 0; i < table->size; i++) { if (table->data[i] != NULL && | | | | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | return; if ((newData = calloc(newSize, sizeof(*newData))) == NULL) OBJC_ERROR("Not enough memory to resize hash table!"); for (uint32_t i = 0; i < table->size; i++) { if (table->data[i] != NULL && table->data[i] != &objc_deletedBucket) { uint32_t j, last; last = newSize; for (j = table->data[i]->hash & (newSize - 1); j < last && newData[j] != NULL; j++); if (j >= last) { last = table->data[i]->hash & (newSize - 1); for (j = 0; j < last && newData[j] != NULL; j++); } if (j >= last) OBJC_ERROR("No free bucket in hash table!"); newData[j] = table->data[i]; } } free(table->data); table->data = newData; table->size = newSize; } static inline bool indexForKey(struct objc_hashtable *table, const void *key, uint32_t *idx) { uint32_t i, hash; hash = table->hash(key) & (table->size - 1); for (i = hash; i < table->size && table->data[i] != NULL; i++) { if (table->data[i] == &objc_deletedBucket) continue; if (table->equal(table->data[i]->key, key)) { *idx = i; return true; } } if (i < table->size) return false; for (i = 0; i < hash && table->data[i] != NULL; i++) { if (table->data[i] == &objc_deletedBucket) continue; if (table->equal(table->data[i]->key, key)) { *idx = i; return true; } } |
︙ | ︙ | |||
179 180 181 182 183 184 185 | resize(table, table->count + 1); hash = table->hash(key); last = table->size; for (i = hash & (table->size - 1); i < last && table->data[i] != NULL && | | | | | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | resize(table, table->count + 1); hash = table->hash(key); last = table->size; for (i = hash & (table->size - 1); i < last && table->data[i] != NULL && table->data[i] != &objc_deletedBucket; i++); if (i >= last) { last = hash & (table->size - 1); for (i = 0; i < last && table->data[i] != NULL && table->data[i] != &objc_deletedBucket; i++); } if (i >= last) OBJC_ERROR("No free bucket in hash table!"); if ((bucket = malloc(sizeof(*bucket))) == NULL) OBJC_ERROR("Not enough memory to allocate hash table bucket!"); bucket->key = key; bucket->hash = hash; bucket->object = object; |
︙ | ︙ | |||
222 223 224 225 226 227 228 | { uint32_t idx; if (!indexForKey(table, key, &idx)) return; free(table->data[idx]); | | | | 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | { uint32_t idx; if (!indexForKey(table, key, &idx)) return; free(table->data[idx]); table->data[idx] = &objc_deletedBucket; table->count--; resize(table, table->count); } void objc_hashtable_free(struct objc_hashtable *table) { for (uint32_t i = 0; i < table->size; i++) if (table->data[i] != NULL && table->data[i] != &objc_deletedBucket) free(table->data[i]); free(table->data); free(table); } |
Modified src/runtime/init.m from [89cae05911] to [bad26900aa].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | #import "ObjFWRT.h" #import "private.h" void __objc_exec_class(struct objc_module *module) { | | | | | | | | | | | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #import "ObjFWRT.h" #import "private.h" void __objc_exec_class(struct objc_module *module) { objc_globalMutex_lock(); objc_registerAllSelectors(module->symtab); objc_registerAllClasses(module->symtab); objc_registerAllCategories(module->symtab); objc_initStaticInstances(module->symtab); objc_globalMutex_unlock(); } void objc_deinit(void) { objc_globalMutex_lock(); objc_unregisterAllCategories(); objc_unregisterAllClasses(); objc_unregisterAllSelectors(); objc_forgetPendingStaticInstances(); objc_dtable_cleanup(); objc_globalMutex_unlock(); } |
Modified src/runtime/instance.m from [7b2e36d210] to [bb4ce37e30].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
79 80 81 82 83 84 85 | Class class; void (*last)(id, SEL) = NULL; if (object == nil) return NULL; #ifdef OF_OBJFW_RUNTIME | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | Class class; void (*last)(id, SEL) = NULL; if (object == nil) return NULL; #ifdef OF_OBJFW_RUNTIME objc_zeroWeakReferences(object); #endif if (destructSelector == NULL) destructSelector = sel_registerName(".cxx_destruct"); for (class = object_getClass(object); class != Nil; class = class_getSuperclass(class)) { |
︙ | ︙ |
Modified src/runtime/ivar.m from [a37b0223f2] to [9c027bf0b1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
29 30 31 32 33 34 35 | if (class == Nil) { if (outCount != NULL) *outCount = 0; return NULL; } | | | | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | if (class == Nil) { if (outCount != NULL) *outCount = 0; return NULL; } objc_globalMutex_lock(); count = (class->ivars != NULL ? class->ivars->count : 0); if (count == 0) { if (outCount != NULL) *outCount = 0; objc_globalMutex_unlock(); return NULL; } if ((ivars = malloc((count + 1) * sizeof(Ivar))) == NULL) OBJC_ERROR("Not enough memory to copy ivars!"); for (unsigned int i = 0; i < count; i++) ivars[i] = &class->ivars->ivars[i]; ivars[count] = NULL; if (outCount != NULL) *outCount = count; objc_globalMutex_unlock(); return ivars; } const char * ivar_getName(Ivar ivar) { |
︙ | ︙ |
Modified src/runtime/linklib/Makefile from [90ff5bb4a5] to [dc27346920].
1 2 3 | include ../../../extra.mk STATIC_LIB = libobjfwrt.library.a | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | include ../../../extra.mk STATIC_LIB = libobjfwrt.library.a SRCS = init.m \ linklib.m include ../../../buildsys.mk CPPFLAGS += -I.. -I../.. -I../../.. \ -DOBJC_COMPILING_AMIGA_LINKLIB \ -DOBJFWRT_AMIGA_LIB=\"${OBJFWRT_AMIGA_LIB}\" \ -DOBJFWRT_LIB_MINOR=${OBJFWRT_LIB_MINOR} LD = ${OBJC} |
Added src/runtime/linklib/init.m version [6ddafedf04].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "ObjFWRT.h" #import "private.h" #import "macros.h" #include <proto/exec.h> #include <proto/intuition.h> struct ObjFWRTBase; #include <stdio.h> #include <stdlib.h> #if defined(OF_AMIGAOS_M68K) # include <stabs.h> #elif defined(OF_MORPHOS) # include <constructor.h> #endif #ifdef HAVE_SJLJ_EXCEPTIONS extern int _Unwind_SjLj_RaiseException(void *); #else extern int _Unwind_RaiseException(void *); #endif extern void _Unwind_DeleteException(void *); extern void *_Unwind_GetLanguageSpecificData(void *); extern uintptr_t _Unwind_GetRegionStart(void *); extern uintptr_t _Unwind_GetDataRelBase(void *); extern uintptr_t _Unwind_GetTextRelBase(void *); extern uintptr_t _Unwind_GetIP(void *); extern uintptr_t _Unwind_GetGR(void *, int); extern void _Unwind_SetIP(void *, uintptr_t); extern void _Unwind_SetGR(void *, int, uintptr_t); #ifdef HAVE_SJLJ_EXCEPTIONS extern void _Unwind_SjLj_Resume(void *); #else extern void _Unwind_Resume(void *); #endif #ifdef OF_AMIGAOS_M68K extern void __register_frame_info(const void *, void *); extern void *__deregister_frame_info(const void *); #endif #ifdef OF_MORPHOS extern void __register_frame(void *); extern void __deregister_frame(void *); #endif struct Library *ObjFWRTBase; void *__objc_class_name_Protocol; extern bool objc_init(unsigned int version, struct objc_libc *libc); static void error(const char *string, ULONG arg) { struct Library *IntuitionBase = OpenLibrary("intuition.library", 0); if (IntuitionBase != NULL) { struct EasyStruct easy = { .es_StructSize = sizeof(easy), .es_Flags = 0, .es_Title = (void *)NULL, .es_TextFormat = (void *)string, (void *)"OK" }; EasyRequest(NULL, &easy, NULL, arg); CloseLibrary(IntuitionBase); } exit(EXIT_FAILURE); } static void __attribute__((__used__)) ctor(void) { static bool initialized = false; struct objc_libc libc = { .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free, #ifdef HAVE_SJLJ_EXCEPTIONS ._Unwind_SjLj_RaiseException = _Unwind_SjLj_RaiseException, #else ._Unwind_RaiseException = _Unwind_RaiseException, #endif ._Unwind_DeleteException = _Unwind_DeleteException, ._Unwind_GetLanguageSpecificData = _Unwind_GetLanguageSpecificData, ._Unwind_GetRegionStart = _Unwind_GetRegionStart, ._Unwind_GetDataRelBase = _Unwind_GetDataRelBase, ._Unwind_GetTextRelBase = _Unwind_GetTextRelBase, ._Unwind_GetIP = _Unwind_GetIP, ._Unwind_GetGR = _Unwind_GetGR, ._Unwind_SetIP = _Unwind_SetIP, ._Unwind_SetGR = _Unwind_SetGR, #ifdef HAVE_SJLJ_EXCEPTIONS ._Unwind_SjLj_Resume = _Unwind_SjLj_Resume, #else ._Unwind_Resume = _Unwind_Resume, #endif #ifdef OF_AMIGAOS_M68K .__register_frame_info = __register_frame_info, .__deregister_frame_info = __deregister_frame_info, #endif #ifdef OF_MORPHOS .__register_frame = __register_frame, .__deregister_frame = __deregister_frame, #endif #ifdef OF_AMIGAOS_M68K .vsnprintf = vsnprintf, #endif .atexit = atexit, .exit = exit, }; if (initialized) return; if ((ObjFWRTBase = OpenLibrary(OBJFWRT_AMIGA_LIB, OBJFWRT_LIB_MINOR)) == NULL) error("Failed to open " OBJFWRT_AMIGA_LIB " version %lu!", OBJFWRT_LIB_MINOR); if (!objc_init(1, &libc)) error("Failed to initialize " OBJFWRT_AMIGA_LIB "!", 0); initialized = true; } static void __attribute__((__used__)) dtor(void) { CloseLibrary(ObjFWRTBase); } #if defined(OF_AMIGAOS_M68K) ADD2INIT(ctor, -5) ADD2EXIT(dtor, -5) #elif defined(OF_MORPHOS) CONSTRUCTOR_P(ObjFWRT, 4000) { ctor(); return 0; } DESTRUCTOR_P(ObjFWRT, 0) { dtor(); } #endif extern int __gnu_objc_personality(int version, int actions, uint64_t *exClass, void *ex, void *ctx); int #ifdef HAVE_SJLJ_EXCEPTIONS __gnu_objc_personality_sj0( #else __gnu_objc_personality_v0( #endif int version, int actions, uint64_t exClass, void *ex, void *ctx) { #ifdef OF_AMIGAOS_M68K return __gnu_objc_personality(version, actions, &exClass, ex, ctx); #else return __gnu_objc_personality(version, actions, &exClass, ex, ctx); #endif } |
Modified src/runtime/linklib/linklib.m from [f6ecf9cc72] to [0c00bc31d2].
1 | /* | < < | > > | > < > > | > > > > > > > | > < > > | | < > > | < | > > | > > > | > | | < | < > > | < < < < | | | | | | < | > | > < < | | < > > | < > > | > > > > > > | < < < < < < < < < | < < < > | < > > > | | | | | | | | > | < > < < < < < | < < < < < | < > | < | > > > > > > > | | | < > < < < | < > | | | > > > | < | | > < > > < < | | | < < | | | < > > | | < | < < < < < > | < < | < | > > > > > > > | > | < < < < < | < | | < < | > | | < < < | | < < < < | | < > | < > > | | > > > > > > > > > | > > | | < < < < < < < < < < | < < > | > > > > | > | > > > > > > > > > | > > | > > > | > > > > > | > > | | > | > > > > > > > > > | > > | < < < > > > > > > > > > > > > > | > > > > > > > > > | | | > | < > > > | < > > > > > > > > > | | > > > > > > > > | < > > > | < < < < < | < > > > | > > > > > > > | > > > | > > > > > > | > > > > | > | < | | < < < | | > > > | > > | > | > | | | < | | < > > > | < < > > > > | > | > | | > > > > > > > > > | > > | | > > > > > > > > > | > > | | > > > > > > > > > | > > > > > > > > > > > | < > | > | < > > | | < < | > | | > > > > > | < > > | < > < < > | | | > > > > > | < > > | | < < | > | < > > > > > > | | > | | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > | > > > > > > > > > | > > | | < < > > > > | | | > > | < > > > > > > > | < > > > > > > | < > > > > > > > | < > | > > > > > | < > > | | > > > > > > > > > | > > > > | < < < < | > | | > > > > > | | > | > > > > > > > > > | > > | > > > > > > > > > | > > | | > > > > > > > > > | > > | > > > > > > > > > | > > | | > > > > > > > > > | > > | | > > > > > > > > > | > > | > > > > > > > > > | > > | > > > > > > > > > | > > | < < > > > > > > > > > > > > > | | > > > > > > > > > | > > | | > > > | > > > > > | > > | > | | > > > > > > > > > | > > | < > > > > > > > > > | > | > > > | | | | > > > > > > | | | | | > > > > > > > > > | > > > > > > > > > > > > > > > > > > | > | > > > > > > > > > | > > | | > > > > > > > > | | > | < < < < | > > > > > > > > > | > > | > > > > > > > > > | > > > > > > | > > | < > > > > > | < > > | > > > > > > > > > | > > > > > > > > > > > > | < > | | | > | | > > > > > > > > > | > > | > > > > > > > > > | > > > | > > | > > | | > > > > > | | > | | > > > > > > > > > | > > > > > > > > | | | > > > > | < > > | > > > > > > > > > | > > > > > > > > > > > > > > | < < | | > | | > > > > > > > > > | > > | | > > > > > > > > > | > > | | > > > > > > > > > | > > | | > > > > > > > > > | > > > > > > > > > > > > > > > > > > | < > > > > > > > > > > > | > > | | > | > > > > > > > | | | < < < | > > > > > > > > > | > > | | > > > > > > > > > | > > > > > | > | > | < > > > > > | | > | > > > | > > > > > > | | > > > > > > > > > > | | | > | | > | > > > > > > > > > | > > | > > > > > > > > > | > > > > > > > > > > > | > > | > > > > > > > > > | > > | > > > | < | | < > > > | | > | > > > > > > > > > | > > | > > > > > > > > > | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ /* This file is automatically generated from amiga-library.xml */ #include "config.h" #import "ObjFWRT.h" #import "private.h" extern struct Library *ObjFWRTBase; bool objc_init(unsigned int version, struct objc_libc *libc) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((bool (*)(unsigned int __asm__("d0"), struct objc_libc *__asm__("a0")))(((uintptr_t)ObjFWRTBase) - 30))(version, libc); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((bool (*)(unsigned int, struct objc_libc *))*(void **)(((uintptr_t)ObjFWRTBase) - 28))(version, libc); #endif } void __objc_exec_class(struct objc_module *_Nonnull module) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(struct objc_module *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 36))(module); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(struct objc_module *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 34))(module); #endif } IMP _Nonnull objc_msg_lookup(id _Nullable object, SEL _Nonnull selector) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((IMP _Nonnull (*)(id _Nullable __asm__("a0"), SEL _Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 42))(object, selector); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((IMP _Nonnull (*)(id _Nullable, SEL _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 40))(object, selector); #endif } IMP _Nonnull objc_msg_lookup_stret(id _Nullable object, SEL _Nonnull selector) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((IMP _Nonnull (*)(id _Nullable __asm__("a0"), SEL _Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 48))(object, selector); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((IMP _Nonnull (*)(id _Nullable, SEL _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 46))(object, selector); #endif } IMP _Nonnull objc_msg_lookup_super(struct objc_super *_Nonnull super, SEL _Nonnull selector) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((IMP _Nonnull (*)(struct objc_super *_Nonnull __asm__("a0"), SEL _Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 54))(super, selector); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((IMP _Nonnull (*)(struct objc_super *_Nonnull, SEL _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 52))(super, selector); #endif } IMP _Nonnull objc_msg_lookup_super_stret(struct objc_super *_Nonnull super, SEL _Nonnull selector) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((IMP _Nonnull (*)(struct objc_super *_Nonnull __asm__("a0"), SEL _Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 60))(super, selector); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((IMP _Nonnull (*)(struct objc_super *_Nonnull, SEL _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 58))(super, selector); #endif } Class _Nullable objc_lookUpClass(const char *_Nonnull name) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Class _Nullable (*)(const char *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 66))(name); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Class _Nullable (*)(const char *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 64))(name); #endif } Class _Nullable objc_getClass(const char *_Nonnull name) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Class _Nullable (*)(const char *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 72))(name); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Class _Nullable (*)(const char *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 70))(name); #endif } Class _Nonnull objc_getRequiredClass(const char *_Nonnull name) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Class _Nonnull (*)(const char *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 78))(name); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Class _Nonnull (*)(const char *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 76))(name); #endif } Class _Nullable objc_lookup_class(const char *_Nonnull name) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Class _Nullable (*)(const char *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 84))(name); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Class _Nullable (*)(const char *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 82))(name); #endif } Class _Nonnull objc_get_class(const char *_Nonnull name) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Class _Nonnull (*)(const char *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 90))(name); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Class _Nonnull (*)(const char *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 88))(name); #endif } void objc_exception_throw(id _Nonnull object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(id _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 96))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(id _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 94))(object); #endif OF_UNREACHABLE } int objc_sync_enter(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((int (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 102))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((int (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 100))(object); #endif } int objc_sync_exit(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((int (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 108))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((int (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 106))(object); #endif } id _Nullable objc_getProperty(id _Nonnull self, SEL _Nonnull _cmd, ptrdiff_t offset, bool atomic) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nonnull __asm__("a0"), SEL _Nonnull __asm__("a1"), ptrdiff_t __asm__("d0"), bool __asm__("d1")))(((uintptr_t)ObjFWRTBase) - 114))(self, _cmd, offset, atomic); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nonnull, SEL _Nonnull, ptrdiff_t, bool))*(void **)(((uintptr_t)ObjFWRTBase) - 112))(self, _cmd, offset, atomic); #endif } void objc_setProperty(id _Nonnull self, SEL _Nonnull _cmd, ptrdiff_t offset, id _Nullable value, bool atomic, signed char copy) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(id _Nonnull __asm__("a0"), SEL _Nonnull __asm__("a1"), ptrdiff_t __asm__("d0"), id _Nullable __asm__("a2"), bool __asm__("d1"), signed char __asm__("d2")))(((uintptr_t)ObjFWRTBase) - 120))(self, _cmd, offset, value, atomic, copy); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(id _Nonnull, SEL _Nonnull, ptrdiff_t, id _Nullable, bool, signed char))*(void **)(((uintptr_t)ObjFWRTBase) - 118))(self, _cmd, offset, value, atomic, copy); #endif } void objc_getPropertyStruct(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(void *_Nonnull __asm__("a0"), const void *_Nonnull __asm__("a1"), ptrdiff_t __asm__("d0"), bool __asm__("d1"), bool __asm__("d2")))(((uintptr_t)ObjFWRTBase) - 126))(dest, src, size, atomic, strong); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(void *_Nonnull, const void *_Nonnull, ptrdiff_t, bool, bool))*(void **)(((uintptr_t)ObjFWRTBase) - 124))(dest, src, size, atomic, strong); #endif } void objc_setPropertyStruct(void *_Nonnull dest, const void *_Nonnull src, ptrdiff_t size, bool atomic, bool strong) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(void *_Nonnull __asm__("a0"), const void *_Nonnull __asm__("a1"), ptrdiff_t __asm__("d0"), bool __asm__("d1"), bool __asm__("d2")))(((uintptr_t)ObjFWRTBase) - 132))(dest, src, size, atomic, strong); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(void *_Nonnull, const void *_Nonnull, ptrdiff_t, bool, bool))*(void **)(((uintptr_t)ObjFWRTBase) - 130))(dest, src, size, atomic, strong); #endif } void objc_enumerationMutation(id _Nonnull object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(id _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 138))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(id _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 136))(object); #endif } int __gnu_objc_personality(int version, int actions, uint64_t *_Nonnull exClass, void *_Nonnull ex, void *_Nonnull ctx) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((int (*)(int __asm__("d0"), int __asm__("d1"), uint64_t *_Nonnull __asm__("d2"), void *_Nonnull __asm__("a0"), void *_Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 144))(version, actions, exClass, ex, ctx); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((int (*)(int, int, uint64_t *_Nonnull, void *_Nonnull, void *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 142))(version, actions, exClass, ex, ctx); #endif } id _Nullable objc_retain(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 150))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 148))(object); #endif } id _Nullable objc_retainBlock(id _Nullable block) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 156))(block); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 154))(block); #endif } id _Nullable objc_retainAutorelease(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 162))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 160))(object); #endif } void objc_release(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 168))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 166))(object); #endif } id _Nullable objc_autorelease(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 174))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 172))(object); #endif } id _Nullable objc_autoreleaseReturnValue(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 180))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 178))(object); #endif } id _Nullable objc_retainAutoreleaseReturnValue(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 186))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 184))(object); #endif } id _Nullable objc_retainAutoreleasedReturnValue(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 192))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 190))(object); #endif } id _Nullable objc_storeStrong(id _Nullable *_Nonnull object, id _Nullable value) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable *_Nonnull __asm__("a0"), id _Nullable __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 198))(object, value); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable *_Nonnull, id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 196))(object, value); #endif } id _Nullable objc_storeWeak(id _Nullable *_Nonnull object, id _Nullable value) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable *_Nonnull __asm__("a0"), id _Nullable __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 204))(object, value); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable *_Nonnull, id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 202))(object, value); #endif } id _Nullable objc_loadWeakRetained(id _Nullable *_Nonnull object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 210))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 208))(object); #endif } id _Nullable objc_initWeak(id _Nullable *_Nonnull object, id _Nullable value) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable *_Nonnull __asm__("a0"), id _Nullable __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 216))(object, value); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable *_Nonnull, id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 214))(object, value); #endif } void objc_destroyWeak(id _Nullable *_Nonnull object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(id _Nullable *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 222))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(id _Nullable *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 220))(object); #endif } id _Nullable objc_loadWeak(id _Nullable *_Nonnull object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 228))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 226))(object); #endif } void objc_copyWeak(id _Nullable *_Nonnull dest, id _Nullable *_Nonnull src) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(id _Nullable *_Nonnull __asm__("a0"), id _Nullable *_Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 234))(dest, src); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(id _Nullable *_Nonnull, id _Nullable *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 232))(dest, src); #endif } void objc_moveWeak(id _Nullable *_Nonnull dest, id _Nullable *_Nonnull src) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(id _Nullable *_Nonnull __asm__("a0"), id _Nullable *_Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 240))(dest, src); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(id _Nullable *_Nonnull, id _Nullable *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 238))(dest, src); #endif } SEL _Nonnull sel_registerName(const char *_Nonnull name) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((SEL _Nonnull (*)(const char *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 246))(name); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((SEL _Nonnull (*)(const char *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 244))(name); #endif } const char *_Nonnull sel_getName(SEL _Nonnull selector) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((const char *_Nonnull (*)(SEL _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 252))(selector); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((const char *_Nonnull (*)(SEL _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 250))(selector); #endif } bool sel_isEqual(SEL _Nonnull selector1, SEL _Nonnull selector2) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((bool (*)(SEL _Nonnull __asm__("a0"), SEL _Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 258))(selector1, selector2); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((bool (*)(SEL _Nonnull, SEL _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 256))(selector1, selector2); #endif } Class _Nonnull objc_allocateClassPair(Class _Nullable superclass, const char *_Nonnull name, size_t extraBytes) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Class _Nonnull (*)(Class _Nullable __asm__("a0"), const char *_Nonnull __asm__("a1"), size_t __asm__("d0")))(((uintptr_t)ObjFWRTBase) - 264))(superclass, name, extraBytes); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Class _Nonnull (*)(Class _Nullable, const char *_Nonnull, size_t))*(void **)(((uintptr_t)ObjFWRTBase) - 262))(superclass, name, extraBytes); #endif } void objc_registerClassPair(Class _Nonnull class) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(Class _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 270))(class); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(Class _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 268))(class); #endif } unsigned int objc_getClassList(Class _Nonnull *_Nullable buffer, unsigned int count) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((unsigned int (*)(Class _Nonnull *_Nullable __asm__("a0"), unsigned int __asm__("d0")))(((uintptr_t)ObjFWRTBase) - 276))(buffer, count); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((unsigned int (*)(Class _Nonnull *_Nullable, unsigned int))*(void **)(((uintptr_t)ObjFWRTBase) - 274))(buffer, count); #endif } Class _Nonnull *_Nonnull objc_copyClassList(unsigned int *_Nullable length) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Class _Nonnull *_Nonnull (*)(unsigned int *_Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 282))(length); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Class _Nonnull *_Nonnull (*)(unsigned int *_Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 280))(length); #endif } bool class_isMetaClass(Class _Nullable class) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((bool (*)(Class _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 288))(class); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((bool (*)(Class _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 286))(class); #endif } const char *_Nullable class_getName(Class _Nullable class) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((const char *_Nullable (*)(Class _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 294))(class); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((const char *_Nullable (*)(Class _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 292))(class); #endif } Class _Nullable class_getSuperclass(Class _Nullable class) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Class _Nullable (*)(Class _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 300))(class); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Class _Nullable (*)(Class _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 298))(class); #endif } unsigned long class_getInstanceSize(Class _Nullable class) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((unsigned long (*)(Class _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 306))(class); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((unsigned long (*)(Class _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 304))(class); #endif } bool class_respondsToSelector(Class _Nullable class, SEL _Nonnull selector) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((bool (*)(Class _Nullable __asm__("a0"), SEL _Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 312))(class, selector); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((bool (*)(Class _Nullable, SEL _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 310))(class, selector); #endif } bool class_conformsToProtocol(Class _Nullable class, Protocol *_Nonnull p) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((bool (*)(Class _Nullable __asm__("a0"), Protocol *_Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 318))(class, p); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((bool (*)(Class _Nullable, Protocol *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 316))(class, p); #endif } IMP _Nullable class_getMethodImplementation(Class _Nullable class, SEL _Nonnull selector) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((IMP _Nullable (*)(Class _Nullable __asm__("a0"), SEL _Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 324))(class, selector); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((IMP _Nullable (*)(Class _Nullable, SEL _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 322))(class, selector); #endif } IMP _Nullable class_getMethodImplementation_stret(Class _Nullable class, SEL _Nonnull selector) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((IMP _Nullable (*)(Class _Nullable __asm__("a0"), SEL _Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 330))(class, selector); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((IMP _Nullable (*)(Class _Nullable, SEL _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 328))(class, selector); #endif } Method _Nullable class_getInstanceMethod(Class _Nullable class, SEL _Nonnull selector) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Method _Nullable (*)(Class _Nullable __asm__("a0"), SEL _Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 336))(class, selector); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Method _Nullable (*)(Class _Nullable, SEL _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 334))(class, selector); #endif } bool class_addMethod(Class _Nonnull class, SEL _Nonnull selector, IMP _Nonnull implementation, const char *_Nullable typeEncoding) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((bool (*)(Class _Nonnull __asm__("a0"), SEL _Nonnull __asm__("a1"), IMP _Nonnull __asm__("a2"), const char *_Nullable __asm__("a3")))(((uintptr_t)ObjFWRTBase) - 342))(class, selector, implementation, typeEncoding); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((bool (*)(Class _Nonnull, SEL _Nonnull, IMP _Nonnull, const char *_Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 340))(class, selector, implementation, typeEncoding); #endif } IMP _Nullable class_replaceMethod(Class _Nonnull class, SEL _Nonnull selector, IMP _Nonnull implementation, const char *_Nullable typeEncoding) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((IMP _Nullable (*)(Class _Nonnull __asm__("a0"), SEL _Nonnull __asm__("a1"), IMP _Nonnull __asm__("a2"), const char *_Nullable __asm__("a3")))(((uintptr_t)ObjFWRTBase) - 348))(class, selector, implementation, typeEncoding); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((IMP _Nullable (*)(Class _Nonnull, SEL _Nonnull, IMP _Nonnull, const char *_Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 346))(class, selector, implementation, typeEncoding); #endif } Class _Nullable object_getClass(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Class _Nullable (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 354))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Class _Nullable (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 352))(object); #endif } Class _Nullable object_setClass(id _Nullable object, Class _Nonnull class) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Class _Nullable (*)(id _Nullable __asm__("a0"), Class _Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 360))(object, class); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Class _Nullable (*)(id _Nullable, Class _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 358))(object, class); #endif } const char *_Nullable object_getClassName(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((const char *_Nullable (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 366))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((const char *_Nullable (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 364))(object); #endif } const char *_Nonnull protocol_getName(Protocol *_Nonnull protocol) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((const char *_Nonnull (*)(Protocol *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 372))(protocol); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((const char *_Nonnull (*)(Protocol *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 370))(protocol); #endif } bool protocol_isEqual(Protocol *_Nonnull protocol1, Protocol *_Nonnull protocol2) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((bool (*)(Protocol *_Nonnull __asm__("a0"), Protocol *_Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 378))(protocol1, protocol2); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((bool (*)(Protocol *_Nonnull, Protocol *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 376))(protocol1, protocol2); #endif } bool protocol_conformsToProtocol(Protocol *_Nonnull protocol1, Protocol *_Nonnull protocol2) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((bool (*)(Protocol *_Nonnull __asm__("a0"), Protocol *_Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 384))(protocol1, protocol2); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((bool (*)(Protocol *_Nonnull, Protocol *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 382))(protocol1, protocol2); #endif } _Nullable objc_uncaught_exception_handler objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler _Nullable handler) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((_Nullable objc_uncaught_exception_handler (*)(objc_uncaught_exception_handler _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 390))(handler); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((_Nullable objc_uncaught_exception_handler (*)(objc_uncaught_exception_handler _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 388))(handler); #endif } void objc_setForwardHandler(IMP _Nullable forward, IMP _Nullable stretForward) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(IMP _Nullable __asm__("a0"), IMP _Nullable __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 396))(forward, stretForward); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(IMP _Nullable, IMP _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 394))(forward, stretForward); #endif } void objc_setEnumerationMutationHandler(objc_enumeration_mutation_handler _Nullable hadler) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(objc_enumeration_mutation_handler _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 402))(hadler); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(objc_enumeration_mutation_handler _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 400))(hadler); #endif } id _Nullable objc_constructInstance(Class _Nullable class, void *_Nullable bytes) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(Class _Nullable __asm__("a0"), void *_Nullable __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 408))(class, bytes); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(Class _Nullable, void *_Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 406))(class, bytes); #endif } void objc_deinit() { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)())(((uintptr_t)ObjFWRTBase) - 414))(); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)())*(void **)(((uintptr_t)ObjFWRTBase) - 412))(); #endif } Ivar _Nullable *_Nullable class_copyIvarList(Class _Nullable class, unsigned int *_Nullable outCount) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Ivar _Nullable *_Nullable (*)(Class _Nullable __asm__("a0"), unsigned int *_Nullable __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 420))(class, outCount); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Ivar _Nullable *_Nullable (*)(Class _Nullable, unsigned int *_Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 418))(class, outCount); #endif } const char *_Nonnull ivar_getName(Ivar _Nonnull ivar) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((const char *_Nonnull (*)(Ivar _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 426))(ivar); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((const char *_Nonnull (*)(Ivar _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 424))(ivar); #endif } const char *_Nonnull ivar_getTypeEncoding(Ivar _Nonnull ivar) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((const char *_Nonnull (*)(Ivar _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 432))(ivar); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((const char *_Nonnull (*)(Ivar _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 430))(ivar); #endif } ptrdiff_t ivar_getOffset(Ivar _Nonnull ivar) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((ptrdiff_t (*)(Ivar _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 438))(ivar); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((ptrdiff_t (*)(Ivar _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 436))(ivar); #endif } Method _Nullable *_Nullable class_copyMethodList(Class _Nullable class, unsigned int *_Nullable outCount) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((Method _Nullable *_Nullable (*)(Class _Nullable __asm__("a0"), unsigned int *_Nullable __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 444))(class, outCount); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((Method _Nullable *_Nullable (*)(Class _Nullable, unsigned int *_Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 442))(class, outCount); #endif } SEL _Nonnull method_getName(Method _Nonnull method) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((SEL _Nonnull (*)(Method _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 450))(method); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((SEL _Nonnull (*)(Method _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 448))(method); #endif } const char *_Nullable method_getTypeEncoding(Method _Nonnull method) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((const char *_Nullable (*)(Method _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 456))(method); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((const char *_Nullable (*)(Method _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 454))(method); #endif } objc_property_t _Nullable *_Nullable class_copyPropertyList(Class _Nullable class, unsigned int *_Nullable outCount) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((objc_property_t _Nullable *_Nullable (*)(Class _Nullable __asm__("a0"), unsigned int *_Nullable __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 462))(class, outCount); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((objc_property_t _Nullable *_Nullable (*)(Class _Nullable, unsigned int *_Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 460))(class, outCount); #endif } const char *_Nonnull property_getName(objc_property_t _Nonnull property) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((const char *_Nonnull (*)(objc_property_t _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 468))(property); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((const char *_Nonnull (*)(objc_property_t _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 466))(property); #endif } char *_Nullable property_copyAttributeValue(objc_property_t _Nonnull property, const char *_Nonnull name) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((char *_Nullable (*)(objc_property_t _Nonnull __asm__("a0"), const char *_Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 474))(property, name); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((char *_Nullable (*)(objc_property_t _Nonnull, const char *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 472))(property, name); #endif } void *_Nullable objc_destructInstance(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((void *_Nullable (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 480))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((void *_Nullable (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 478))(object); #endif } void *_Null_unspecified objc_autoreleasePoolPush() { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((void *_Null_unspecified (*)())(((uintptr_t)ObjFWRTBase) - 486))(); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((void *_Null_unspecified (*)())*(void **)(((uintptr_t)ObjFWRTBase) - 484))(); #endif } void objc_autoreleasePoolPop(void *_Null_unspecified pool) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(void *_Null_unspecified __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 492))(pool); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(void *_Null_unspecified))*(void **)(((uintptr_t)ObjFWRTBase) - 490))(pool); #endif } id _Nullable _objc_rootAutorelease(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 498))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 496))(object); #endif } struct objc_hashtable *_Nonnull objc_hashtable_new(objc_hashtable_hash_func hash, objc_hashtable_equal_func equal, uint32_t size) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((struct objc_hashtable *_Nonnull (*)(objc_hashtable_hash_func __asm__("a0"), objc_hashtable_equal_func __asm__("a1"), uint32_t __asm__("d0")))(((uintptr_t)ObjFWRTBase) - 504))(hash, equal, size); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((struct objc_hashtable *_Nonnull (*)(objc_hashtable_hash_func, objc_hashtable_equal_func, uint32_t))*(void **)(((uintptr_t)ObjFWRTBase) - 502))(hash, equal, size); #endif } void objc_hashtable_set(struct objc_hashtable *_Nonnull table, const void *_Nonnull key, const void *_Nonnull object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(struct objc_hashtable *_Nonnull __asm__("a0"), const void *_Nonnull __asm__("a1"), const void *_Nonnull __asm__("a2")))(((uintptr_t)ObjFWRTBase) - 510))(table, key, object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(struct objc_hashtable *_Nonnull, const void *_Nonnull, const void *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 508))(table, key, object); #endif } void *_Nullable objc_hashtable_get(struct objc_hashtable *_Nonnull table, const void *_Nonnull key) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((void *_Nullable (*)(struct objc_hashtable *_Nonnull __asm__("a0"), const void *_Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 516))(table, key); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((void *_Nullable (*)(struct objc_hashtable *_Nonnull, const void *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 514))(table, key); #endif } void objc_hashtable_delete(struct objc_hashtable *_Nonnull table, const void *_Nonnull key) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(struct objc_hashtable *_Nonnull __asm__("a0"), const void *_Nonnull __asm__("a1")))(((uintptr_t)ObjFWRTBase) - 522))(table, key); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(struct objc_hashtable *_Nonnull, const void *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 520))(table, key); #endif } void objc_hashtable_free(struct objc_hashtable *_Nonnull table) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(struct objc_hashtable *_Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 528))(table); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(struct objc_hashtable *_Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 526))(table); #endif } void objc_setTaggedPointerSecret(uintptr_t secret) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; ((void (*)(uintptr_t __asm__("d0")))(((uintptr_t)ObjFWRTBase) - 534))(secret); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); __extension__ ((void (*)(uintptr_t))*(void **)(((uintptr_t)ObjFWRTBase) - 532))(secret); #endif } int objc_registerTaggedPointerClass(Class _Nonnull class) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((int (*)(Class _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 540))(class); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((int (*)(Class _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 538))(class); #endif } bool object_isTaggedPointer(id _Nullable object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((bool (*)(id _Nullable __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 546))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((bool (*)(id _Nullable))*(void **)(((uintptr_t)ObjFWRTBase) - 544))(object); #endif } uintptr_t object_getTaggedPointerValue(id _Nonnull object) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((uintptr_t (*)(id _Nonnull __asm__("a0")))(((uintptr_t)ObjFWRTBase) - 552))(object); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((uintptr_t (*)(id _Nonnull))*(void **)(((uintptr_t)ObjFWRTBase) - 550))(object); #endif } id _Nullable objc_createTaggedPointer(int class, uintptr_t value) { #if defined(OF_AMIGAOS_M68K) register struct Library *a6 __asm__("a6") = ObjFWRTBase; (void)a6; return ((id _Nullable (*)(int __asm__("d0"), uintptr_t __asm__("d1")))(((uintptr_t)ObjFWRTBase) - 558))(class, value); #elif defined(OF_MORPHOS) __asm__ __volatile__ ( "mr %%r12, %0" :: "r"(ObjFWRTBase) : "r12" ); return __extension__ ((id _Nullable (*)(int, uintptr_t))*(void **)(((uintptr_t)ObjFWRTBase) - 556))(class, value); #endif } |
Modified src/runtime/lookup-asm/Makefile from [a8b7579307] to [3c7b7f7fc1].
1 2 3 4 5 6 7 8 9 10 | include ../../../extra.mk STATIC_PIC_LIB_NOINST = ${LOOKUP_ASM_LIB_A} STATIC_LIB_NOINST = ${LOOKUP_ASM_A} SRCS = lookup-asm.S include ../../../buildsys.mk ASFLAGS += -I../../.. -I../.. | > > | 1 2 3 4 5 6 7 8 9 10 11 12 | include ../../../extra.mk STATIC_PIC_LIB_NOINST = ${LOOKUP_ASM_LIB_A} STATIC_AMIGA_LIB_NOINST = ${LOOKUP_ASM_AMIGALIB_A} STATIC_LIB_NOINST = ${LOOKUP_ASM_A} SRCS = lookup-asm.S include ../../../buildsys.mk ASFLAGS += -I../../.. -I../.. ASFLAGS_lookup-asm.amigalib.o += -DOF_BASEREL |
Modified src/runtime/lookup-asm/lookup-asm-arm-elf.S from [fae6543de8] to [f0e5b05f4e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound \name: cmp r0, #0 beq returnNilMethod tst r0, #1 bne .LtaggedPointer_\name ldr r2, [r0, #0] ldr r2, [r2, #32] .Lmain_\name: #ifndef OF_BIG_ENDIAN # ifdef OF_SELUID24 |
︙ | ︙ | |||
54 55 56 57 58 59 60 | ldrb r3, [r1, #2] ldr r2, [r2, r3, lsl #2] ldrb r3, [r1, #3] ldr r2, [r2, r3, lsl #2] #endif cmp r2, #0 | | | | | | | | | | | | | | | | | | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | ldrb r3, [r1, #2] ldr r2, [r2, r3, lsl #2] ldrb r3, [r1, #3] ldr r2, [r2, r3, lsl #2] #endif cmp r2, #0 beq \notFound(PLT) mov r0, r2 bx lr .LtaggedPointer_\name: ldr r2, .Lgot$indirect_.LtaggedPointer_\name add r2, pc, r2 ldr r3, .Lgot$indirect_.LtaggedPointer_\name+4 ldr r3, [r2, r3] ldr r3, [r3] eor r0, r0, r3 and r0, r0, #0xE lsl r0, r0, #1 ldr r3, .Lgot$indirect_.LtaggedPointer_\name+8 ldr r3, [r2, r3] ldr r2, [r3, r0] ldr r2, [r2, #32] b .Lmain_\name .type \name, %function .size \name, .-\name .Lgot$indirect_.LtaggedPointer_\name: .long _GLOBAL_OFFSET_TABLE_-(.LtaggedPointer_\name+12) .long objc_taggedPointerSecret(GOT) .long objc_taggedPointerClasses(GOT) .endm .macro GENERATE_LOOKUP_SUPER name lookup \name: mov r2, r0 ldr r0, [r0, #0] cmp r0, #0 beq returnNilMethod ldr r2, [r2, #4] ldr r2, [r2, #32] b .Lmain_\lookup .type \name, %function .size \name, .-\name .endm GENERATE_LOOKUP objc_msg_lookup objc_methodNotFound GENERATE_LOOKUP objc_msg_lookup_stret objc_methodNotFound_stret GENERATE_LOOKUP_SUPER objc_msg_lookup_super objc_msg_lookup GENERATE_LOOKUP_SUPER objc_msg_lookup_super_stret objc_msg_lookup_stret returnNilMethod: adr r0, nilMethod bx lr nilMethod: mov r0, #0 bx lr #ifdef OF_LINUX .section .note.GNU-stack, "", %progbits #endif |
Modified src/runtime/lookup-asm/lookup-asm-arm64-elf.S from [a8a0a8247a] to [ad3c36fa42].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text | | | | | | | | | | | | | | | | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound \name: cbz x0, returnNilMethod tst x0, #1 b.ne .LtaggedPointer_\name ldr x2, [x0] ldr x2, [x2, #64] .Lmain_\name: #ifdef OF_SELUID24 ldrb w3, [x1, #2] ldr x2, [x2, x3, lsl #3] #endif ldrb w3, [x1, #1] ldr x2, [x2, x3, lsl #3] ldrb w3, [x1] ldr x2, [x2, x3, lsl #3] cbz x2, \notFound mov x0, x2 ret .LtaggedPointer_\name: adrp x2, :got:objc_taggedPointerSecret ldr x2, [x2, #:got_lo12:objc_taggedPointerSecret] ldr x2, [x2] eor x0, x0, x2 and x0, x0, #0xE lsl x0, x0, #2 adrp x2, :got:objc_taggedPointerClasses ldr x2, [x2, #:got_lo12:objc_taggedPointerClasses] ldr x2, [x2, x0] ldr x2, [x2, #64] b .Lmain_\name .type \name, %function .size \name, .-\name .endm .macro GENERATE_LOOKUP_SUPER name lookup \name: mov x2, x0 ldr x0, [x0] cbz x0, returnNilMethod ldr x2, [x2, #8] ldr x2, [x2, #64] b .Lmain_\lookup .type \name, %function .size \name, .-\name .endm GENERATE_LOOKUP objc_msg_lookup objc_methodNotFound GENERATE_LOOKUP objc_msg_lookup_stret objc_methodNotFound_stret GENERATE_LOOKUP_SUPER objc_msg_lookup_super objc_msg_lookup GENERATE_LOOKUP_SUPER objc_msg_lookup_super_stret objc_msg_lookup_stret returnNilMethod: adr x0, nilMethod ret nilMethod: mov x0, #0 ret #ifdef OF_LINUX .section .note.GNU-stack, "", %progbits #endif |
Modified src/runtime/lookup-asm/lookup-asm-mips-elf.S from [87115a51c3] to [c727ce9d5a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound \name: beqz $a0, 0f andi $t0, $a0, 1 bnez $t0, .LtaggedPointer_\name lw $t0, 0($a0) lw $t0, 32($t0) .Lmain_\name: #ifdef OF_BIG_ENDIAN # ifdef OF_SELUID24 |
︙ | ︙ | |||
64 65 66 67 68 69 70 | lw $t0, 0($t0) addu $t0, $t0, $t3 lw $t0, 0($t0) #ifdef OF_PIC beqz $t0, 1f #else | | | | | | | | | | | | | | | | | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | lw $t0, 0($t0) addu $t0, $t0, $t3 lw $t0, 0($t0) #ifdef OF_PIC beqz $t0, 1f #else beqz $t0, \notFound #endif move $v0, $t0 jr $ra 0: #ifdef OF_PIC addiu $v0, $t9, nilMethod-\name #else la $v0, nilMethod #endif jr $ra #ifdef OF_PIC 1: lui $gp, %hi(_gp_disp) addiu $gp, $gp, %lo(_gp_disp) addu $gp, $gp, $t9 addiu $gp, $gp, 1b-\name lw $t9, %call16(\notFound)($gp) jr $t9 #endif .LtaggedPointer_\name: #ifdef OF_PIC 0: lui $gp, %hi(_gp_disp) addiu $gp, $gp, %lo(_gp_disp) addu $gp, $gp, $t9 addiu $gp, $gp, 0b-\name lw $t0, %got(objc_taggedPointerSecret)($gp) #else la $t0, objc_taggedPointerSecret #endif lw $t0, 0($t0) xor $t0, $a0, $t0 and $t0, $t0, 0xE sll $t0, $t0, 1 #ifdef OF_PIC lw $t1, %got(objc_taggedPointerClasses)($gp) #else la $t1, objc_taggedPointerClasses #endif addu $t0, $t1, $t0 ld $t0, ($t0) ld $t0, 32($t0) b .Lmain_\name .type \name, %function .size \name, .-\name .endm .macro GENERATE_LOOKUP_SUPER name lookup \name: move $t0, $a0 lw $a0, 0($a0) beqz $a0, 0f lw $t0, 4($t0) lw $t0, 32($t0) addiu $t9, $t9, \lookup-\name b .Lmain_\lookup 0: #ifdef OF_PIC addiu $v0, $t9, nilMethod-\name #else la $v0, nilMethod #endif jr $ra .type \name, %function .size \name, .-\name .endm GENERATE_LOOKUP objc_msg_lookup objc_methodNotFound GENERATE_LOOKUP objc_msg_lookup_stret objc_methodNotFound_stret GENERATE_LOOKUP_SUPER objc_msg_lookup_super objc_msg_lookup GENERATE_LOOKUP_SUPER objc_msg_lookup_super_stret objc_msg_lookup_stret nilMethod: move $v0, $zero jr $ra #ifdef OF_LINUX .section .note.GNU-stack, "", %progbits #endif |
Modified src/runtime/lookup-asm/lookup-asm-mips64-n64-elf.S from [3b31980e08] to [53637868a6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound \name: beqz $a0, 0f andi $t0, $a0, 1 bnez $t0, .LtaggedPointer_\name ld $t0, ($a0) ld $t0, 64($t0) .Lmain_\name: #ifdef OF_BIG_ENDIAN # ifdef OF_SELUID24 |
︙ | ︙ | |||
70 71 72 73 74 75 76 | move $v0, $t0 jr $ra 0: lui $v0, %hi(%neg(%gp_rel(\name))) daddiu $v0, $v0, %lo(%neg(%gp_rel(\name))) daddu $v0, $v0, $t9 | | | | | | | | | | | | | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | move $v0, $t0 jr $ra 0: lui $v0, %hi(%neg(%gp_rel(\name))) daddiu $v0, $v0, %lo(%neg(%gp_rel(\name))) daddu $v0, $v0, $t9 ld $v0, %got_disp(nilMethod)($v0) jr $ra 1: lui $t0, %hi(%neg(%gp_rel(\name))) daddiu $t0, $t0, %lo(%neg(%gp_rel(\name))) daddu $t0, $t0, $t9 ld $t9, %got_disp(\notFound)($t0) jr $t9 .LtaggedPointer_\name: lui $t0, %hi(%neg(%gp_rel(\name))) daddiu $t0, $t0, %lo(%neg(%gp_rel(\name))) daddu $t0, $t0, $t9 ld $t1, %got_disp(objc_taggedPointerSecret)($t0) ld $t1, 0($t1) xor $t1, $a0, $t1 and $t1, $t1, 0xE dsll $t1, $t1, 2 ld $t0, %got_disp(objc_taggedPointerClasses)($t0) daddu $t0, $t0, $t1 ld $t0, ($t0) ld $t0, 64($t0) b .Lmain_\name .type \name, %function .size \name, .-\name .endm .macro GENERATE_LOOKUP_SUPER name lookup \name: move $t0, $a0 ld $a0, ($a0) beqz $a0, 0f ld $t0, 8($t0) ld $t0, 64($t0) daddiu $t9, $t9, \lookup-\name b .Lmain_\lookup 0: lui $v0, %hi(%neg(%gp_rel(\name))) daddiu $v0, $v0, %lo(%neg(%gp_rel(\name))) daddu $v0, $v0, $t9 ld $v0, %got_disp(nilMethod)($v0) jr $ra .type \name, %function .size \name, .-\name .endm GENERATE_LOOKUP objc_msg_lookup objc_methodNotFound GENERATE_LOOKUP objc_msg_lookup_stret objc_methodNotFound_stret GENERATE_LOOKUP_SUPER objc_msg_lookup_super objc_msg_lookup GENERATE_LOOKUP_SUPER objc_msg_lookup_super_stret objc_msg_lookup_stret nilMethod: move $v0, $zero jr $ra #ifdef OF_LINUX .section .note.GNU-stack, "", %progbits #endif |
Modified src/runtime/lookup-asm/lookup-asm-powerpc-elf.S from [6a0efd2f1b] to [134bfef460].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound \name: cmpwi %r3, 0 beq- returnNilMethod andi. %r0, %r3, 1 bne- .LtaggedPointer_\name lwz %r5, 0(%r3) lwz %r5, 32(%r5) .Lmain_\name: lwz %r8, 0(%r4) #ifdef OF_SELUID24 |
︙ | ︙ | |||
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | cmpwi %r5, 0 beq- 0f mr %r3, %r5 blr 0: stwu %r1, -16(%r1) mflr %r0 stw %r0, 20(%r1) stw %r30, 8(%r1) bl 0f 0: mflr %r30 addis %r30, %r30, .Lbiased_got2-0b@ha addi %r30, %r30, .Lbiased_got2-0b@l | > | > > > | > | > > > > > > > > | > > > > > > > | | | | | | | | | | | > | | | | | | | | > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | cmpwi %r5, 0 beq- 0f mr %r3, %r5 blr 0: #ifdef OF_PIC stwu %r1, -16(%r1) mflr %r0 stw %r0, 20(%r1) stw %r30, 8(%r1) bl 0f 0: mflr %r30 addis %r30, %r30, .Lbiased_got2-0b@ha addi %r30, %r30, .Lbiased_got2-0b@l lwz %r0, .Lgot_\notFound-.Lbiased_got2(%r30) mtctr %r0 lwz %r30, 8(%r1) lwz %r0, 20(%r1) addi %r1, %r1, 16 mtlr %r0 bctr #else b \notFound #endif .LtaggedPointer_\name: #if defined(OF_PIC) mflr %r7 bl 0f 0: mflr %r6 mtlr %r7 addis %r6, %r6, .Lbiased_got2-0b@ha addi %r6, %r6, .Lbiased_got2-0b@l lwz %r5, .Lgot_objc_taggedPointerSecret-.Lbiased_got2(%r6) lwz %r5, 0(%r5) #elif defined(OF_BASEREL) addis %r5, %r13, objc_taggedPointerSecret@drel@ha lwz %r5, objc_taggedPointerSecret@drel@l(%r5) #else lis %r5, objc_taggedPointerSecret@ha lwz %r5, objc_taggedPointerSecret@l(%r5) #endif xor %r5, %r3, %r5 rlwinm %r5, %r5, 1, 0x1C #if defined(OF_PIC) lwz %r6, .Lgot_objc_taggedPointerClasses-.Lbiased_got2(%r6) #elif defined(OF_BASEREL) addis %r6, %r13, objc_taggedPointerClasses@drel@ha addi %r6, %r6, objc_taggedPointerClasses@drel@l #else lis %r6, objc_taggedPointerClasses@ha addi %r6, %r6, objc_taggedPointerClasses@l #endif lwzx %r5, %r6, %r5 lwz %r5, 32(%r5) b .Lmain_\name .type \name, @function .size \name, .-\name .endm .macro GENERATE_LOOKUP_SUPER name lookup \name: mr %r5, %r3 lwz %r3, 0(%r3) cmpwi %r3, 0 beq- returnNilMethod lwz %r5, 4(%r5) lwz %r5, 32(%r5) b .Lmain_\lookup .type \name, @function .size \name, .-\name .endm GENERATE_LOOKUP objc_msg_lookup objc_methodNotFound GENERATE_LOOKUP objc_msg_lookup_stret objc_methodNotFound_stret GENERATE_LOOKUP_SUPER objc_msg_lookup_super objc_msg_lookup GENERATE_LOOKUP_SUPER objc_msg_lookup_super_stret objc_msg_lookup_stret returnNilMethod: mflr %r0 bl getPC mtlr %r0 0: addi %r3, %r3, nilMethod-0b blr nilMethod: li %r3, 0 blr getPC: mflr %r3 blr #ifdef OF_PIC .section .got2, "aw" .Lbiased_got2 = .+0x8000 .Lgot_objc_methodNotFound: .long objc_methodNotFound .Lgot_objc_methodNotFound_stret: .long objc_methodNotFound_stret .Lgot_objc_taggedPointerSecret: .long objc_taggedPointerSecret .Lgot_objc_taggedPointerClasses: .long objc_taggedPointerClasses #endif #ifdef OF_LINUX .section .note.GNU-stack, "", @progbits #endif |
Added src/runtime/lookup-asm/lookup-asm-powerpc64-elf.S version [8516ac090f].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" #if defined(_CALL_ELF) && _CALL_ELF == 2 .abiversion 2 #endif .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound #if defined(_CALL_ELF) && _CALL_ELF == 2 \name: addis %r2, %r12, .TOC.-\name@ha addi %r2, %r2, .TOC.-\name@l .localentry \name, .-\name #else .section .opd, "aw", @progbits \name: .p2align 3 .quad .Lbegin_\name .quad .TOC.@tocbase .quad 0 .section .text #endif .Lbegin_\name: cmpdi %r3, 0 beq- .LreturnNilMethod andi. %r0, %r3, 1 bne- .LtaggedPointer_\name ld %r5, 0(%r3) ld %r5, 64(%r5) .Lmain_\name: ld %r8, 0(%r4) #ifdef OF_SELUID24 rlwinm %r6, %r8, 19, 0x7F8 #endif rlwinm %r7, %r8, 27, 0x7F8 rlwinm %r8, %r8, 3, 0x7F8 #ifdef OF_SELUID24 ldx %r5, %r5, %r6 #endif ldx %r5, %r5, %r7 ldx %r5, %r5, %r8 cmpdi %r5, 0 beq- 0f mr %r3, %r5 blr 0: mflr %r0 std %r0, 16(%r1) stdu %r1, -112(%r1) bl \notFound nop addi %r1, %r1, 112 ld %r0, 16(%r1) mtlr %r0 blr .LtaggedPointer_\name: addis %r5, %r2, objc_taggedPointerSecret@toc@ha ld %r5, objc_taggedPointerSecret@toc@l(%r5) xor %r5, %r3, %r5 rlwinm %r5, %r5, 2, 0x38 addis %r6, %r2, objc_taggedPointerClasses@toc@ha addi %r6, %r6, objc_taggedPointerClasses@toc@l ldx %r5, %r6, %r5 ld %r5, 64(%r5) b .Lmain_\name .type \name, @function .size \name, .-.Lbegin_\name .endm .macro GENERATE_LOOKUP_SUPER name lookup #if defined(_CALL_ELF) && _CALL_ELF == 2 \name: addis %r2, %r12, .TOC.-\name@ha addi %r2, %r2, .TOC.-\name@l .localentry \name, .-\name #else .section .opd, "aw", @progbits \name: .p2align 3 .quad .Lbegin_\name .quad .TOC.@tocbase .quad 0 .section .text #endif .Lbegin_\name: mr %r5, %r3 ld %r3, 0(%r3) cmpdi %r3, 0 beq- .LreturnNilMethod ld %r5, 8(%r5) ld %r5, 64(%r5) b .Lmain_\lookup .type \name, @function .size \name, .-.Lbegin_\name .endm GENERATE_LOOKUP objc_msg_lookup objc_methodNotFound GENERATE_LOOKUP objc_msg_lookup_stret objc_methodNotFound_stret GENERATE_LOOKUP_SUPER objc_msg_lookup_super objc_msg_lookup GENERATE_LOOKUP_SUPER objc_msg_lookup_super_stret objc_msg_lookup_stret .LreturnNilMethod: addis %r3, %r2, nilMethod@toc@ha addi %r3, %r3, nilMethod@toc@l blr #if defined(_CALL_ELF) && _CALL_ELF == 2 nilMethod: addis %r2, %r12, .TOC.-nilMethod@ha addi %r2, %r2, .TOC.-nilMethod@l .localentry nilMethod, .-nilMethod #else .section .opd, "aw", @progbits nilMethod: .p2align 3 .quad .Lbegin_nilMethod .quad .TOC.@tocbase .quad 0 .section .text #endif .Lbegin_nilMethod: li %r3, 0 blr .type nilMethod, @function .size nilMethod, .-.Lbegin_nilMethod #ifdef OF_LINUX .section .note.GNU-stack, "", @progbits #endif |
Modified src/runtime/lookup-asm/lookup-asm-sparc-elf.S from [ee867480c0] to [52b9093b5b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound \name: tst %o0 bz returnNilMethod btst 1, %o0 bnz .LtaggedPointer_\name nop ld [%o0], %o2 ld [%o2 + 32], %o2 .Lmain_\name: #ifdef OF_SELUID24 |
︙ | ︙ | |||
60 61 62 63 64 65 66 | nop retl mov %o2, %o0 0: mov %o7, %g1 | | | | | | | | | | | | | | | | | | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | nop retl mov %o2, %o0 0: mov %o7, %g1 call \notFound mov %g1, %o7 .LtaggedPointer_\name: #ifdef OF_PIC mov %o7, %g1 sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %o3 call 0f or %o3, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %o3 0: add %o7, %o3, %o3 mov %g1, %o7 #endif sethi %hi(objc_taggedPointerSecret), %o2 or %o2, %lo(objc_taggedPointerSecret), %o2 #ifdef OF_PIC ld [%o3 + %o2], %o2 #endif ld [%o2], %o2 xor %o0, %o2, %o0 and %o0, 0xE, %o0 sll %o0, 1, %o0 sethi %hi(objc_taggedPointerClasses), %o2 or %o2, %lo(objc_taggedPointerClasses), %o2 #ifdef OF_PIC ld [%o3 + %o2], %o2 #endif ld [%o2 + %o0], %o2 ba .Lmain_\name ld [%o2 + 32], %o2 .type \name, %function .size \name, .-\name .endm .macro GENERATE_LOOKUP_SUPER name lookup \name: mov %o0, %o2 ld [%o0], %o0 cmp %o0, 0 be returnNilMethod nop ld [%o2 + 4], %o2 ba .Lmain_\lookup ld [%o2 + 32], %o2 .type \name, %function .size \name, .-\name .endm GENERATE_LOOKUP objc_msg_lookup objc_methodNotFound GENERATE_LOOKUP objc_msg_lookup_stret objc_methodNotFound_stret GENERATE_LOOKUP_SUPER objc_msg_lookup_super objc_msg_lookup GENERATE_LOOKUP_SUPER objc_msg_lookup_super_stret objc_msg_lookup_stret returnNilMethod: #ifdef OF_PIC mov %o7, %g1 sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %o1 call 0f add %o1, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %o1 0: add %o7, %o1, %o1 sethi %hi(nilMethod), %o0 or %o0, %lo(nilMethod), %o0 jmpl %g1 + 8, %g0 ld [%o1 + %o0], %o0 #else sethi %hi(nilMethod), %o0 retl or %o0, %lo(nilMethod), %o0 #endif nilMethod: retl clr %o0 #ifdef OF_LINUX .section .note.GNU-stack, "", %progbits #endif |
Modified src/runtime/lookup-asm/lookup-asm-sparc64-elf.S from [b56d827aa1] to [1e61b50ef6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound \name: brz,pn %o0, returnNilMethod and %o0, 1, %o2 brnz,pn %o2, .LtaggedPointer_\name nop ldx [%o0], %o2 ldx [%o2 + 64], %o2 .Lmain_\name: #ifdef OF_SELUID24 |
︙ | ︙ | |||
58 59 60 61 62 63 64 | nop retl mov %o2, %o0 0: mov %o7, %g1 | | | | | | | | | | | | | | | | | | | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | nop retl mov %o2, %o0 0: mov %o7, %g1 call \notFound mov %g1, %o7 .LtaggedPointer_\name: #ifdef OF_PIC mov %o7, %g1 sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %o3 call 0f or %o3, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %o3 0: add %o7, %o3, %o3 mov %g1, %o7 #endif sethi %hi(objc_taggedPointerSecret), %o2 or %o2, %lo(objc_taggedPointerSecret), %o2 #ifdef OF_PIC ldx [%o3 + %o2], %o2 #endif ldx [%o2], %o2 xor %o0, %o2, %o0 and %o0, 0xE, %o0 sll %o0, 2, %o0 sethi %hi(objc_taggedPointerClasses), %o2 or %o2, %lo(objc_taggedPointerClasses), %o2 #ifdef OF_PIC ldx [%o3 + %o2], %o2 #endif ldx [%o2 + %o0], %o2 ba .Lmain_\name ldx [%o2 + 64], %o2 .type \name, %function .size \name, .-\name .endm .macro GENERATE_LOOKUP_SUPER name lookup \name: mov %o0, %o2 ldx [%o0], %o0 brz,pn %o0, returnNilMethod nop ldx [%o2 + 8], %o2 ba .Lmain_\lookup ldx [%o2 + 64], %o2 .type \name, %function .size \name, .-\name .endm GENERATE_LOOKUP objc_msg_lookup objc_methodNotFound GENERATE_LOOKUP objc_msg_lookup_stret objc_methodNotFound_stret GENERATE_LOOKUP_SUPER objc_msg_lookup_super objc_msg_lookup GENERATE_LOOKUP_SUPER objc_msg_lookup_super_stret objc_msg_lookup_stret returnNilMethod: #ifdef OF_PIC mov %o7, %g1 sethi %hi(_GLOBAL_OFFSET_TABLE_ - 4), %o1 call 0f or %o1, %lo(_GLOBAL_OFFSET_TABLE_ + 4), %o1 0: add %o7, %o1, %o1 sethi %hi(nilMethod), %o0 or %o0, %lo(nilMethod), %o0 jmpl %g1 + 8, %g0 ldx [%o1 + %o0], %o0 #else sethi %hi(nilMethod), %o0 retl or %o0, %lo(nilMethod), %o0 #endif nilMethod: retl clr %o0 #ifdef OF_LINUX .section .note.GNU-stack, "", %progbits #endif |
Modified src/runtime/lookup-asm/lookup-asm-x86-elf.S from [3e4a512a7a] to [fe04c47c7f].
1 | /* | < < | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | < | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound \name: movl 4(%esp), %edx testl %edx, %edx jz returnNilMethod testb $1, %dl jnz .LtaggedPointer_\name movl (%edx), %edx movl 32(%edx), %edx .Lmain_\name: movl 8(%esp), %eax #ifdef OF_SELUID24 movzbl 2(%eax), %ecx movl (%edx,%ecx,4), %edx #endif movzbl 1(%eax), %ecx movl (%edx,%ecx,4), %edx movzbl (%eax), %ecx movl (%edx,%ecx,4), %eax testl %eax, %eax jz 0f ret 0: call getEIP addl $_GLOBAL_OFFSET_TABLE_, %eax lea \notFound@GOTOFF(%eax), %eax jmp *%eax .LtaggedPointer_\name: call getEIP addl $_GLOBAL_OFFSET_TABLE_, %eax leal objc_taggedPointerSecret@GOTOFF(%eax), %ecx xorl (%ecx), %edx andb $0xE, %dl movzbl %dl, %edx leal objc_taggedPointerClasses@GOTOFF(%eax), %eax movl (%eax,%edx,2), %edx movl 32(%edx), %edx jmp .Lmain_\name .type \name, %function .size \name, .-\name .endm .macro GENERATE_LOOKUP_SUPER name lookup \name: movl 4(%esp), %edx movl (%edx), %eax testl %eax, %eax jz returnNilMethod movl %eax, 4(%esp) mov 4(%edx), %edx mov 32(%edx), %edx jmp .Lmain_\lookup .type \name, %function .size \name, .-\name .endm GENERATE_LOOKUP objc_msg_lookup objc_methodNotFound GENERATE_LOOKUP objc_msg_lookup_stret objc_methodNotFound_stret GENERATE_LOOKUP_SUPER objc_msg_lookup_super objc_msg_lookup GENERATE_LOOKUP_SUPER objc_msg_lookup_super_stret objc_msg_lookup_stret returnNilMethod: call getEIP addl $_GLOBAL_OFFSET_TABLE_, %eax leal nilMethod@GOTOFF(%eax), %eax ret nilMethod: xorl %eax, %eax ret getEIP: movl (%esp), %eax ret #ifdef OF_LINUX .section .note.GNU-stack, "", %progbits #endif |
Modified src/runtime/lookup-asm/lookup-asm-x86-win32.S from [5502257c39] to [0d663a9140].
1 | /* | < < | < < | | | | | | | | | | | | | | | | | | | | | | | | > > > > > | < | | | | | | | | > > > > | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" .globl _objc_msg_lookup .globl _objc_msg_lookup_stret .globl _objc_msg_lookup_super .globl _objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound \name: movl 4(%esp), %edx testl %edx, %edx jz returnNilMethod testb $1, %dl jnz .LtaggedPointer_\name movl (%edx), %edx movl 32(%edx), %edx .Lmain_\name: movl 8(%esp), %eax #ifdef OF_SELUID24 movzbl 2(%eax), %ecx movl (%edx,%ecx,4), %edx #endif movzbl 1(%eax), %ecx movl (%edx,%ecx,4), %edx movzbl (%eax), %ecx movl (%edx,%ecx,4), %eax testl %eax, %eax jz \notFound ret .LtaggedPointer_\name: xorl _objc_taggedPointerSecret, %edx andb $0xE, %dl movzbl %dl, %edx movl _objc_taggedPointerClasses(,%edx,2), %edx movl 32(%edx), %edx jmp .Lmain_\name .def \name .scl 2 .type 32 .endef .endm .macro GENERATE_LOOKUP_SUPER name lookup \name: movl 4(%esp), %edx movl (%edx), %eax test %eax, %eax jz returnNilMethod movl %eax, 4(%esp) movl 4(%edx), %edx movl 32(%edx), %edx jmp .Lmain_\lookup .def \name .scl 2 .type 32 .endef .endm GENERATE_LOOKUP _objc_msg_lookup _objc_methodNotFound GENERATE_LOOKUP _objc_msg_lookup_stret _objc_methodNotFound_stret GENERATE_LOOKUP_SUPER _objc_msg_lookup_super _objc_msg_lookup GENERATE_LOOKUP_SUPER _objc_msg_lookup_super_stret _objc_msg_lookup_stret returnNilMethod: movl $nilMethod, %eax ret nilMethod: xorl %eax, %eax ret |
Modified src/runtime/lookup-asm/lookup-asm-x86_64-elf.S from [1f89a766d7] to [63daf9ee68].
1 | /* | < < | < < | | | | | | | | | | | | | | | | | | | > | | | < | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include "platform.h" .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound \name: testq %rdi, %rdi jz returnNilMethod testb $1, %dil jnz .LtaggedPointer_\name movq (%rdi), %r8 movq 64(%r8), %r8 .Lmain_\name: movq (%rsi), %rax movzbl %ah, %ecx movzbl %al, %edx #ifdef OF_SELUID24 shrl $16, %eax movq (%r8,%rax,8), %r8 #endif movq (%r8,%rcx,8), %r8 movq (%r8,%rdx,8), %rax testq %rax, %rax jz \notFound@PLT ret .LtaggedPointer_\name: movq objc_taggedPointerSecret@GOTPCREL(%rip), %rax xorq (%rax), %rdi andb $0xE, %dil movzbl %dil, %r8d movq objc_taggedPointerClasses@GOTPCREL(%rip), %rax movq (%rax,%r8,4), %r8 movq 64(%r8), %r8 jmp .Lmain_\name .type \name, %function .size \name, .-\name .endm .macro GENERATE_LOOKUP_SUPER name lookup \name: movq %rdi, %r8 movq (%rdi), %rdi testq %rdi, %rdi jz returnNilMethod movq 8(%r8), %r8 movq 64(%r8), %r8 jmp .Lmain_\lookup .type \name, %function .size \name, .-\name .endm GENERATE_LOOKUP objc_msg_lookup objc_methodNotFound GENERATE_LOOKUP objc_msg_lookup_stret objc_methodNotFound_stret GENERATE_LOOKUP_SUPER objc_msg_lookup_super objc_msg_lookup GENERATE_LOOKUP_SUPER objc_msg_lookup_super_stret objc_msg_lookup_stret returnNilMethod: leaq nilMethod(%rip), %rax ret nilMethod: xorq %rax, %rax ret #ifdef OF_LINUX .section .note.GNU-stack, "", %progbits #endif |
Modified src/runtime/lookup-asm/lookup-asm-x86_64-macho.S from [1d842ab593] to [1e72bfb083].
1 | /* | < < | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" .globl _objc_msg_lookup .globl _objc_msg_lookup_stret .globl _objc_msg_lookup_super .globl _objc_msg_lookup_super_stret .section __TEXT, __text, regular, pure_instructions .macro GENERATE_LOOKUP $0: testq %rdi, %rdi jz returnNilMethod testb $$1, %dil jnz LtaggedPointer_$0 movq (%rdi), %r8 movq 64(%r8), %r8 Lmain_$0: movq (%rsi), %rax movzbl %ah, %ecx movzbl %al, %edx #ifdef OF_SELUID24 shrl $$16, %eax movq (%r8,%rax,8), %r8 #endif movq (%r8,%rcx,8), %r8 movq (%r8,%rdx,8), %rax testq %rax, %rax jz $1 ret LtaggedPointer_$0: movq _objc_taggedPointerSecret@GOTPCREL(%rip), %rax xorq (%rax), %rdi andb $$0xE, %dil movzbl %dil, %r8d movq _objc_taggedPointerClasses@GOTPCREL(%rip), %rax movq (%rax,%r8,4), %r8 movq 64(%r8), %r8 jmp Lmain_$0 .endmacro .macro GENERATE_LOOKUP_SUPER $0: movq %rdi, %r8 movq (%rdi), %rdi testq %rdi, %rdi jz returnNilMethod movq 8(%r8), %r8 movq 64(%r8), %r8 jmp Lmain_$1 .endmacro GENERATE_LOOKUP _objc_msg_lookup, _objc_methodNotFound GENERATE_LOOKUP _objc_msg_lookup_stret, _objc_methodNotFound_stret GENERATE_LOOKUP_SUPER _objc_msg_lookup_super, _objc_msg_lookup GENERATE_LOOKUP_SUPER _objc_msg_lookup_super_stret, _objc_msg_lookup_stret returnNilMethod: leaq nilMethod(%rip), %rax ret nilMethod: xorq %rax, %rax ret |
Modified src/runtime/lookup-asm/lookup-asm-x86_64-win64.S from [fde9955f30] to [bb874856c9].
1 | /* | < < | < < | | | | | | | | | | | | | | | | | | | | | | | | | | > | | > > > > | < < | < > > > | | | > > > > | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" .globl objc_msg_lookup .globl objc_msg_lookup_stret .globl objc_msg_lookup_super .globl objc_msg_lookup_super_stret .section .text .macro GENERATE_LOOKUP name notFound \name: testq %rcx, %rcx jz returnNilMethod testb $1, %cl jnz .LtaggedPointer_\name movq (%rcx), %r8 movq 56(%r8), %r8 .Lmain_\name: movq %rcx, %r10 movq %rdx, %r11 movq (%rdx), %rax movzbl %ah, %ecx movzbl %al, %edx #ifdef OF_SELUID24 shrl $16, %eax movq (%r8,%rax,8), %r8 #endif movq (%r8,%rcx,8), %r8 movq (%r8,%rdx,8), %rax testq %rax, %rax jz 0f ret 0: movq %r10, %rcx movq %r11, %rdx jmp \notFound .LtaggedPointer_\name: xorq objc_taggedPointerSecret(%rip), %rcx andb $0xE, %cl movzbl %cl, %r8d leaq objc_taggedPointerClasses(%rip), %rax movq (%rax,%r8,4), %r8 movq 56(%r8), %r8 jmp .Lmain_\name .def \name .scl 2 .type 32 .endef .endm .macro GENERATE_LOOKUP_SUPER name lookup \name: movq %rcx, %r8 movq (%rcx), %rcx testq %rcx, %rcx jz returnNilMethod movq 8(%r8), %r8 movq 56(%r8), %r8 jmp .Lmain_\lookup .def \name .scl 2 .type 32 .endef .endm GENERATE_LOOKUP objc_msg_lookup objc_methodNotFound GENERATE_LOOKUP objc_msg_lookup_stret objc_methodNotFound_stret GENERATE_LOOKUP_SUPER objc_msg_lookup_super objc_msg_lookup GENERATE_LOOKUP_SUPER objc_msg_lookup_super_stret objc_msg_lookup_stret returnNilMethod: leaq nilMethod(%rip), %rax ret nilMethod: xorq %rax, %rax ret |
Modified src/runtime/lookup-asm/lookup-asm.S from [4908be8ba8] to [31f647ad96].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 34 35 36 37 | # include "lookup-asm-x86_64-elf.S" # elif defined(OF_X86) # include "lookup-asm-x86-elf.S" # elif defined(OF_ARM64) # include "lookup-asm-arm64-elf.S" # elif defined(OF_ARM) # include "lookup-asm-arm-elf.S" # elif defined(OF_POWERPC) # include "lookup-asm-powerpc-elf.S" # elif defined(OF_MIPS64_N64) # include "lookup-asm-mips64-n64-elf.S" # elif defined(OF_MIPS) # include "lookup-asm-mips-elf.S" # elif defined(OF_SPARC64) | > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | # include "lookup-asm-x86_64-elf.S" # elif defined(OF_X86) # include "lookup-asm-x86-elf.S" # elif defined(OF_ARM64) # include "lookup-asm-arm64-elf.S" # elif defined(OF_ARM) # include "lookup-asm-arm-elf.S" # elif defined(OF_POWERPC64) # include "lookup-asm-powerpc64-elf.S" # elif defined(OF_POWERPC) # include "lookup-asm-powerpc-elf.S" # elif defined(OF_MIPS64_N64) # include "lookup-asm-mips64-n64-elf.S" # elif defined(OF_MIPS) # include "lookup-asm-mips-elf.S" # elif defined(OF_SPARC64) |
︙ | ︙ |
Modified src/runtime/lookup.m from [507e90722d] to [620b9cc132].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
39 40 41 42 43 44 45 | bool isClass = object_getClass(object)->info & OBJC_CLASS_INFO_METACLASS; if (!(object_getClass(object)->info & OBJC_CLASS_INFO_INITIALIZED)) { Class class = (isClass ? (Class)object : object_getClass(object)); | | | > | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | bool isClass = object_getClass(object)->info & OBJC_CLASS_INFO_METACLASS; if (!(object_getClass(object)->info & OBJC_CLASS_INFO_INITIALIZED)) { Class class = (isClass ? (Class)object : object_getClass(object)); objc_initializeClass(class); if (!(class->info & OBJC_CLASS_INFO_SETUP)) OBJC_ERROR("Could not dispatch message %s for " "incomplete class %s!", sel_getName(selector), class_getName(class)); /* * We don't need to handle the case that super was called. * The reason for this is that a call to super is not possible * before a message to the class has been sent and it thus has * been initialized together with its superclasses. */ |
︙ | ︙ | |||
95 96 97 98 99 100 101 | OBJC_ERROR("Selector %c[%s] is not implemented for class %s!", (isClass ? '+' : '-'), sel_getName(selector), object_getClassName(object)); } IMP | | | | | | | | | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | OBJC_ERROR("Selector %c[%s] is not implemented for class %s!", (isClass ? '+' : '-'), sel_getName(selector), object_getClassName(object)); } IMP objc_methodNotFound(id object, SEL selector) { return commonMethodNotFound(object, selector, objc_msg_lookup, forwardHandler); } IMP objc_methodNotFound_stret(id object, SEL selector) { return commonMethodNotFound(object, selector, objc_msg_lookup_stret, stretForwardHandler); } void objc_setForwardHandler(IMP forward, IMP stretForward) { forwardHandler = forward; stretForwardHandler = stretForward; } bool class_respondsToSelector(Class class, SEL selector) { if (class == Nil) return false; return (objc_dtable_get(class->dTable, (uint32_t)selector->UID) != (IMP)0); } #ifndef OF_ASM_LOOKUP static id nilMethod(id self, SEL _cmd) { return nil; } static OF_INLINE IMP commonLookup(id object, SEL selector, IMP (*notFound)(id, SEL)) { IMP imp; if (object == nil) return (IMP)nilMethod; imp = objc_dtable_get(object_getClass(object)->dTable, (uint32_t)selector->UID); if (imp == (IMP)0) return notFound(object, selector); return imp; } IMP objc_msg_lookup(id object, SEL selector) { return commonLookup(object, selector, objc_methodNotFound); } IMP objc_msg_lookup_stret(id object, SEL selector) { return commonLookup(object, selector, objc_methodNotFound_stret); } static OF_INLINE IMP commonSuperLookup(struct objc_super *super, SEL selector, IMP (*notFound)(id, SEL)) { IMP imp; if (super->self == nil) return (IMP)nilMethod; imp = objc_dtable_get(super->class->dTable, (uint32_t)selector->UID); if (imp == (IMP)0) return notFound(super->self, selector); return imp; } IMP objc_msg_lookup_super(struct objc_super *super, SEL selector) { return commonSuperLookup(super, selector, objc_methodNotFound); } IMP objc_msg_lookup_super_stret(struct objc_super *super, SEL selector) { return commonSuperLookup(super, selector, objc_methodNotFound_stret); } #endif |
Modified src/runtime/method.m from [f841e4b2e6] to [82646e77ef].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
30 31 32 33 34 35 36 | if (class == Nil) { if (outCount != NULL) *outCount = 0; return NULL; } | | | > | > > | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | if (class == Nil) { if (outCount != NULL) *outCount = 0; return NULL; } objc_globalMutex_lock(); count = 0; for (iter = class->methodList; iter != NULL; iter = iter->next) count += iter->count; if (count == 0) { if (outCount != NULL) *outCount = 0; objc_globalMutex_unlock(); return NULL; } if ((methods = malloc((count + 1) * sizeof(Method))) == NULL) OBJC_ERROR("Not enough memory to copy methods"); i = 0; for (iter = class->methodList; iter != NULL; iter = iter->next) for (unsigned int j = 0; j < iter->count; j++) methods[i++] = &iter->methods[j]; if (i != count) OBJC_ERROR("Fatal internal inconsistency!"); methods[count] = NULL; if (outCount != NULL) *outCount = count; objc_globalMutex_unlock(); return methods; } SEL method_getName(Method method) { |
︙ | ︙ |
Modified src/runtime/misc.m from [a61bf65bf6] to [6b0956b061].
1 | /* | < < | > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include "ObjFWRT.h" #include "private.h" #ifdef OF_WINDOWS # include <windows.h> #endif #ifdef OF_AMIGAOS # define USE_INLINE_STDARG # include <proto/exec.h> # include <clib/debug_protos.h> # define __NOLIBBASE__ # define Class IntuitionClass # include <proto/intuition.h> # undef Class # undef __NOLIBBASE__ #endif static objc_enumeration_mutation_handler enumerationMutationHandler = NULL; void objc_enumerationMutation(id object) { if (enumerationMutationHandler != NULL) enumerationMutationHandler(object); else OBJC_ERROR("Object was mutated during enumeration!"); } void objc_setEnumerationMutationHandler(objc_enumeration_mutation_handler handler) { enumerationMutationHandler = handler; } void objc_error(const char *title, const char *format, ...) { #if defined(OF_WINDOWS) || defined(OF_AMIGAOS) # define messageLen 512 char message[messageLen]; int status; va_list args; va_start(args, format); status = vsnprintf(message, messageLen, format, args); if (status <= 0 || status >= messageLen) message[0] = '\0'; va_end(args); # undef BUF_LEN #endif #if defined(OF_WINDOWS) fprintf(stderr, "[%s] %s\n", title, message); fflush(stderr); MessageBoxA(NULL, message, title, MB_OK | MB_SYSTEMMODAL | MB_ICONERROR); exit(EXIT_FAILURE); #elif defined(OF_AMIGAOS) struct Library *IntuitionBase; # ifdef OF_AMIGAOS4 struct IntuitionIFace *IIntuition; # endif struct EasyStruct easy; # ifndef OF_AMIGAOS4 kprintf("[%s] %s\n", title, message); # endif if ((IntuitionBase = OpenLibrary("intuition.library", 0)) == NULL) exit(EXIT_FAILURE); # ifdef OF_AMIGAOS4 if ((IIntuition = (struct IntuitionIFace *)GetInterface(IntuitionBase, "main", 1, NULL)) == NULL) exit(EXIT_FAILURE); # endif easy.es_StructSize = sizeof(easy); easy.es_Flags = 0; easy.es_Title = (void *)title; easy.es_TextFormat = (void *)"%s"; easy.es_GadgetFormat = (void *)"OK"; EasyRequest(NULL, &easy, NULL, (ULONG)message); # ifdef OF_AMIGAOS4 DropInterface((struct Interface *)IIntuition); # endif CloseLibrary(IntuitionBase); exit(EXIT_FAILURE); #else va_list args; va_start(args, format); fprintf(stderr, "[%s] ", title); vfprintf(stderr, format, args); fprintf(stderr, "\n"); fflush(stderr); va_end(args); abort(); #endif OF_UNREACHABLE } char * objc_strdup(const char *string) { char *copy; size_t length = strlen(string); if ((copy = (char *)malloc(length + 1)) == NULL) return NULL; memcpy(copy, string, length + 1); return copy; } |
Deleted src/runtime/morphos-clib.h version [252cb36e71].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/runtime/morphos.fd version [881a580162].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified src/runtime/private.h from [7f0c22271c] to [4e60c9110b].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
38 39 40 41 42 43 44 | Class _Nullable superclass; const char *_Nonnull name; unsigned long version; unsigned long info; long instanceSize; struct objc_ivar_list *_Nullable ivars; struct objc_method_list *_Nullable methodList; | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | Class _Nullable superclass; const char *_Nonnull name; unsigned long version; unsigned long info; long instanceSize; struct objc_ivar_list *_Nullable ivars; struct objc_method_list *_Nullable methodList; struct objc_dtable *_Nonnull dTable; Class _Nullable *_Nullable subclassList; void *_Nullable siblingClass; struct objc_protocol_list *_Nullable protocols; void *_Nullable GCObjectType; unsigned long ABIVersion; int32_t *_Nonnull *_Nullable ivarOffsets; struct objc_property_list *_Nullable propertyList; |
︙ | ︙ | |||
199 200 201 202 203 204 205 | struct objc_hashtable_bucket *_Nonnull *_Nullable data; }; struct objc_sparsearray { struct objc_sparsearray_data { void *_Nullable next[256]; } *_Nonnull data; | | | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | struct objc_hashtable_bucket *_Nonnull *_Nullable data; }; struct objc_sparsearray { struct objc_sparsearray_data { void *_Nullable next[256]; } *_Nonnull data; uint8_t levels; }; struct objc_dtable { struct objc_dtable_level2 { #ifdef OF_SELUID24 struct objc_dtable_level3 { IMP _Nullable buckets[256]; |
︙ | ︙ | |||
221 222 223 224 225 226 227 | #if defined(OBJC_COMPILING_AMIGA_LIBRARY) || \ defined(OBJC_COMPILING_AMIGA_LINKLIB) struct objc_libc { void *_Nullable (*_Nonnull malloc)(size_t); void *_Nullable (*_Nonnull calloc)(size_t, size_t); void *_Nullable (*_Nonnull realloc)(void *_Nullable, size_t); void (*_Nonnull free)(void *_Nullable); | < < < > > > > > > > > > > > > | > | < > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > | > < < < < < < < < < < | 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | #if defined(OBJC_COMPILING_AMIGA_LIBRARY) || \ defined(OBJC_COMPILING_AMIGA_LINKLIB) struct objc_libc { void *_Nullable (*_Nonnull malloc)(size_t); void *_Nullable (*_Nonnull calloc)(size_t, size_t); void *_Nullable (*_Nonnull realloc)(void *_Nullable, size_t); void (*_Nonnull free)(void *_Nullable); # ifdef HAVE_SJLJ_EXCEPTIONS int (*_Nonnull _Unwind_SjLj_RaiseException)(void *_Nonnull); # else int (*_Nonnull _Unwind_RaiseException)(void *_Nonnull); # endif void (*_Nonnull _Unwind_DeleteException)(void *_Nonnull); void *_Nullable (*_Nonnull _Unwind_GetLanguageSpecificData)( void *_Nonnull); uintptr_t (*_Nonnull _Unwind_GetRegionStart)(void *_Nonnull); uintptr_t (*_Nonnull _Unwind_GetDataRelBase)(void *_Nonnull); uintptr_t (*_Nonnull _Unwind_GetTextRelBase)(void *_Nonnull); uintptr_t (*_Nonnull _Unwind_GetIP)(void *_Nonnull); uintptr_t (*_Nonnull _Unwind_GetGR)(void *_Nonnull, int); void (*_Nonnull _Unwind_SetIP)(void *_Nonnull, uintptr_t); void (*_Nonnull _Unwind_SetGR)(void *_Nonnull, int, uintptr_t); # ifdef HAVE_SJLJ_EXCEPTIONS void (*_Nonnull _Unwind_SjLj_Resume)(void *_Nonnull); # else void (*_Nonnull _Unwind_Resume)(void *_Nonnull); # endif # ifdef OF_AMIGAOS_M68K void (*_Nonnull __register_frame_info)(const void *_Nonnull, void *_Nonnull); void *(*_Nonnull __deregister_frame_info)(const void *_Nonnull); # endif # ifdef OF_MORPHOS void (*_Nonnull __register_frame)(void *_Nonnull); void (*_Nonnull __deregister_frame)(void *_Nonnull); # endif # ifdef OF_AMIGAOS_M68K int (*_Nonnull vsnprintf)(char *restrict _Nonnull str, size_t size, const char *_Nonnull restrict fmt, va_list args); # endif int (*_Nonnull atexit)(void (*_Nonnull)(void)); void (*_Nonnull exit)(int); }; #endif #ifdef OBJC_COMPILING_AMIGA_LIBRARY # if defined(__MORPHOS__) # include <ppcinline/macros.h> # define OBJC_M68K_ARG(type, name, reg) type name = (type)REG_##reg; # else # define OBJC_M68K_ARG(type, name, reg) \ register type reg_##name __asm__(#reg); \ type name = reg_##name; # endif extern bool objc_init(unsigned int, struct objc_libc *); # ifdef HAVE_SJLJ_EXCEPTIONS # define __gnu_objc_personality(version, actions, exClass, ex, ctx) \ __gnu_objc_personality_sj0(version, actions, *exClass, ex, ctx) # else # define __gnu_objc_personality(version, actions, exClass, ex, ctx) \ __gnu_objc_personality_v0(version, actions, *exClass, ex, ctx) # endif #endif extern void objc_registerAllCategories(struct objc_symtab *_Nonnull); extern struct objc_category *_Nullable *_Nullable objc_categoriesForClass(Class _Nonnull); extern void objc_unregisterAllCategories(void); extern void objc_initializeClass(Class _Nonnull); extern void objc_updateDTable(Class _Nonnull); extern void objc_registerAllClasses(struct objc_symtab *_Nonnull); extern Class _Nullable objc_classnameToClass(const char *_Nonnull, bool); extern void objc_unregisterClass(Class _Nonnull); extern void objc_unregisterAllClasses(void); extern uint32_t objc_string_hash(const void *_Nonnull); extern bool objc_string_equal(const void *_Nonnull, const void *_Nonnull); extern struct objc_hashtable *_Nonnull objc_hashtable_new( objc_hashtable_hash_func, objc_hashtable_equal_func, uint32_t); extern struct objc_hashtable_bucket objc_deletedBucket; extern void objc_hashtable_set(struct objc_hashtable *_Nonnull, const void *_Nonnull, const void *_Nonnull); extern void *_Nullable objc_hashtable_get(struct objc_hashtable *_Nonnull, const void *_Nonnull); extern void objc_hashtable_delete(struct objc_hashtable *_Nonnull, const void *_Nonnull); extern void objc_hashtable_free(struct objc_hashtable *_Nonnull); extern void objc_registerSelector(struct objc_selector *_Nonnull); extern void objc_registerAllSelectors(struct objc_symtab *_Nonnull); extern void objc_unregisterAllSelectors(void); extern struct objc_sparsearray *_Nonnull objc_sparsearray_new(uint8_t); extern void *_Nullable objc_sparsearray_get(struct objc_sparsearray *_Nonnull, uintptr_t); extern void objc_sparsearray_set(struct objc_sparsearray *_Nonnull, uintptr_t, void *_Nullable); extern void objc_sparsearray_free(struct objc_sparsearray *_Nonnull); extern struct objc_dtable *_Nonnull objc_dtable_new(void); extern void objc_dtable_copy(struct objc_dtable *_Nonnull, struct objc_dtable *_Nonnull); extern void objc_dtable_set(struct objc_dtable *_Nonnull, uint32_t, IMP _Nullable); extern void objc_dtable_free(struct objc_dtable *_Nonnull); extern void objc_dtable_cleanup(void); extern void objc_initStaticInstances(struct objc_symtab *_Nonnull); extern void objc_forgetPendingStaticInstances(void); extern void objc_zeroWeakReferences(id _Nonnull); extern Class _Nullable object_getTaggedPointerClass(id _Nonnull); #ifdef OF_HAVE_THREADS extern void objc_globalMutex_lock(void); extern void objc_globalMutex_unlock(void); extern void objc_globalMutex_free(void); #else # define objc_globalMutex_lock() # define objc_globalMutex_unlock() # define objc_globalMutex_free() #endif extern char *_Nullable objc_strdup(const char *_Nonnull string); static inline IMP _Nullable objc_dtable_get(const struct objc_dtable *_Nonnull dtable, uint32_t idx) { #ifdef OF_SELUID24 uint8_t i = idx >> 16; uint8_t j = idx >> 8; uint8_t k = idx; return dtable->buckets[i]->buckets[j]->buckets[k]; #else uint8_t i = idx >> 8; uint8_t j = idx; return dtable->buckets[i]->buckets[j]; #endif } extern void OF_NO_RETURN_FUNC objc_error(const char *_Nonnull title, const char *_Nonnull format, ...); #define OBJC_ERROR(...) \ objc_error("ObjFWRT @ " __FILE__ ":" OF_STRINGIFY(__LINE__), \ __VA_ARGS__) #if defined(OF_ELF) # if defined(OF_X86_64) || defined(OF_X86) || \ defined(OF_POWERPC64) || defined(OF_POWERPC) || \ defined(OF_ARM64) || defined(OF_ARM) || \ defined(OF_MIPS64_N64) || defined(OF_MIPS) || \ defined(OF_SPARC64) || defined(OF_SPARC) # define OF_ASM_LOOKUP # endif #elif defined(OF_MACH_O) # if defined(OF_X86_64) # define OF_ASM_LOOKUP # endif #elif defined(OF_WINDOWS) # if defined(OF_X86_64) || defined(OF_X86) # define OF_ASM_LOOKUP # endif #endif @interface DummyObject { Class _Nonnull isa; } @property (readonly, nonatomic) bool allowsWeakReference; |
︙ | ︙ |
Modified src/runtime/property.m from [f51e3c1883] to [822a1641e1].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | #include <string.h> #import "ObjFWRT.h" #import "private.h" #ifdef OF_HAVE_THREADS | | | > | > | > > > | | | | | > | > | | > | > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | #include <string.h> #import "ObjFWRT.h" #import "private.h" #ifdef OF_HAVE_THREADS # import "OFPlainMutex.h" # define numSpinlocks 8 /* needs to be a power of 2 */ static OFSpinlock spinlocks[numSpinlocks]; static OF_INLINE size_t spinlockSlot(const void *ptr) { return ((size_t)((uintptr_t)ptr >> 4) & (numSpinlocks - 1)); } #endif #ifdef OF_HAVE_THREADS OF_CONSTRUCTOR() { for (size_t i = 0; i < numSpinlocks; i++) if (OFSpinlockNew(&spinlocks[i]) != 0) OBJC_ERROR("Failed to create spinlocks!"); } #endif id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, bool atomic) { if (atomic) { id *ptr = (id *)(void *)((char *)self + offset); #ifdef OF_HAVE_THREADS size_t slot = spinlockSlot(ptr); if (OFSpinlockLock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to lock spinlock!"); @try { return [[*ptr retain] autorelease]; } @finally { if (OFSpinlockUnlock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to unlock spinlock!"); } #else return [[*ptr retain] autorelease]; #endif } return *(id *)(void *)((char *)self + offset); } void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id value, bool atomic, signed char copy) { if (atomic) { id *ptr = (id *)(void *)((char *)self + offset); #ifdef OF_HAVE_THREADS size_t slot = spinlockSlot(ptr); if (OFSpinlockLock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to lock spinlock!"); @try { #endif id old = *ptr; switch (copy) { case 0: *ptr = [value retain]; break; case 2: *ptr = [value mutableCopy]; break; default: *ptr = [value copy]; } [old release]; #ifdef OF_HAVE_THREADS } @finally { if (OFSpinlockUnlock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to unlock spinlock!"); } #endif return; } id *ptr = (id *)(void *)((char *)self + offset); |
︙ | ︙ | |||
115 116 117 118 119 120 121 | /* The following methods are only required for GCC >= 4.6 */ void objc_getPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic, bool strong) { if (atomic) { #ifdef OF_HAVE_THREADS | | | > | > | | > | > | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | /* The following methods are only required for GCC >= 4.6 */ void objc_getPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic, bool strong) { if (atomic) { #ifdef OF_HAVE_THREADS size_t slot = spinlockSlot(src); if (OFSpinlockLock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to lock spinlock!"); #endif memcpy(dest, src, size); #ifdef OF_HAVE_THREADS if (OFSpinlockUnlock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to unlock spinlock!"); #endif return; } memcpy(dest, src, size); } void objc_setPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic, bool strong) { if (atomic) { #ifdef OF_HAVE_THREADS size_t slot = spinlockSlot(src); if (OFSpinlockLock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to lock spinlock!"); #endif memcpy(dest, src, size); #ifdef OF_HAVE_THREADS if (OFSpinlockUnlock(&spinlocks[slot]) != 0) OBJC_ERROR("Failed to unlock spinlock!"); #endif return; } memcpy(dest, src, size); } |
︙ | ︙ | |||
165 166 167 168 169 170 171 | if (class == Nil) { if (outCount != NULL) *outCount = 0; return NULL; } | | | > | > > | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 | if (class == Nil) { if (outCount != NULL) *outCount = 0; return NULL; } objc_globalMutex_lock(); count = 0; if (class->info & OBJC_CLASS_INFO_NEW_ABI) for (iter = class->propertyList; iter != NULL; iter = iter->next) count += iter->count; if (count == 0) { if (outCount != NULL) *outCount = 0; objc_globalMutex_unlock(); return NULL; } properties = malloc((count + 1) * sizeof(objc_property_t)); if (properties == NULL) OBJC_ERROR("Not enough memory to copy properties"); i = 0; for (iter = class->propertyList; iter != NULL; iter = iter->next) for (unsigned int j = 0; j < iter->count; j++) properties[i++] = &iter->properties[j]; if (i != count) OBJC_ERROR("Fatal internal inconsistency!"); properties[count] = NULL; if (outCount != NULL) *outCount = count; objc_globalMutex_unlock(); return properties; } const char * property_getName(objc_property_t property) { |
︙ | ︙ | |||
217 218 219 220 221 222 223 | bool nullIsError = false; if (strlen(name) != 1) return NULL; switch (*name) { case 'T': | | | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | bool nullIsError = false; if (strlen(name) != 1) return NULL; switch (*name) { case 'T': ret = objc_strdup(property->getter.typeEncoding); nullIsError = true; break; case 'G': if (property->attributes & OBJC_PROPERTY_GETTER) { ret = objc_strdup(property->getter.name); nullIsError = true; } break; case 'S': if (property->attributes & OBJC_PROPERTY_SETTER) { ret = objc_strdup(property->setter.name); nullIsError = true; } break; #define BOOL_CASE(name, field, flag) \ case name: \ if (property->field & flag) { \ ret = calloc(1, 1); \ |
︙ | ︙ | |||
251 252 253 254 255 256 257 | BOOL_CASE('D', extendedAttributes, OBJC_PROPERTY_DYNAMIC) BOOL_CASE('W', extendedAttributes, OBJC_PROPERTY_WEAK) #undef BOOL_CASE } if (nullIsError && ret == NULL) OBJC_ERROR("Not enough memory to copy property attribute " | | | 265 266 267 268 269 270 271 272 273 274 275 | BOOL_CASE('D', extendedAttributes, OBJC_PROPERTY_DYNAMIC) BOOL_CASE('W', extendedAttributes, OBJC_PROPERTY_WEAK) #undef BOOL_CASE } if (nullIsError && ret == NULL) OBJC_ERROR("Not enough memory to copy property attribute " "value!"); return ret; } |
Modified src/runtime/protocol.m from [1569f85418] to [30a1ffceef].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
65 66 67 68 69 70 71 | for (struct objc_protocol_list *protocolList = class->protocols; protocolList != NULL; protocolList = protocolList->next) for (long i = 0; i < protocolList->count; i++) if (protocol_conformsToProtocol(protocolList->list[i], protocol)) return true; | | | | | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | for (struct objc_protocol_list *protocolList = class->protocols; protocolList != NULL; protocolList = protocolList->next) for (long i = 0; i < protocolList->count; i++) if (protocol_conformsToProtocol(protocolList->list[i], protocol)) return true; objc_globalMutex_lock(); if ((categories = objc_categoriesForClass(class)) == NULL) { objc_globalMutex_unlock(); return false; } for (long i = 0; categories[i] != NULL; i++) { for (struct objc_protocol_list *protocolList = categories[i]->protocols; protocolList != NULL; protocolList = protocolList->next) { for (long j = 0; j < protocolList->count; j++) { if (protocol_conformsToProtocol( protocolList->list[j], protocol)) { objc_globalMutex_unlock(); return true; } } } } objc_globalMutex_unlock(); return false; } |
Modified src/runtime/selector.m from [6cde6e59e2] to [9a44ebdc88].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | #import "ObjFWRT.h" #import "private.h" #import "macros.h" #ifdef OF_SELUID24 | | | | | | | | | | | | < < | | | | | | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | #import "ObjFWRT.h" #import "private.h" #import "macros.h" #ifdef OF_SELUID24 static const uint32_t maxSel = 0xFFFFFF; static const uint8_t selLevels = 3; #else static const uint32_t maxSel = 0xFFFF; static const uint8_t selLevels = 2; #endif static struct objc_hashtable *selectors = NULL; static uint32_t selectorsCount = 0; static struct objc_sparsearray *selectorNames = NULL; static void **freeList = NULL; static size_t freeListCount = 0; void objc_registerSelector(struct objc_selector *selector) { SEL existingSelector; const char *name; if (selectorsCount > maxSel) OBJC_ERROR("Out of selector slots!"); if (selectors == NULL) selectors = objc_hashtable_new( objc_string_hash, objc_string_equal, 2); else if ((existingSelector = objc_hashtable_get(selectors, (const char *)selector->UID)) != NULL) { selector->UID = existingSelector->UID; return; } if (selectorNames == NULL) selectorNames = objc_sparsearray_new(selLevels); name = (const char *)selector->UID; selector->UID = selectorsCount++; objc_hashtable_set(selectors, name, selector); objc_sparsearray_set(selectorNames, (uint32_t)selector->UID, (void *)name); } SEL sel_registerName(const char *name) { struct objc_selector *selector; objc_globalMutex_lock(); if (selectors != NULL && (selector = objc_hashtable_get(selectors, name)) != NULL) { objc_globalMutex_unlock(); return (SEL)selector; } if ((selector = malloc(sizeof(*selector))) == NULL || (selector->UID = (uintptr_t)objc_strdup(name)) == 0) OBJC_ERROR("Not enough memory to allocate selector!"); selector->typeEncoding = NULL; if ((freeList = realloc(freeList, sizeof(void *) * (freeListCount + 2))) == NULL) OBJC_ERROR("Not enough memory to allocate selector!"); freeList[freeListCount++] = selector; freeList[freeListCount++] = (char *)selector->UID; objc_registerSelector(selector); objc_globalMutex_unlock(); return (SEL)selector; } void objc_registerAllSelectors(struct objc_symtab *symtab) { struct objc_selector *selector; if (symtab->selectorRefs == NULL) return; for (selector = symtab->selectorRefs; selector->UID != 0; selector++) objc_registerSelector(selector); } const char * sel_getName(SEL selector) { const char *ret; objc_globalMutex_lock(); ret = objc_sparsearray_get(selectorNames, (uint32_t)selector->UID); objc_globalMutex_unlock(); return ret; } bool sel_isEqual(SEL selector1, SEL selector2) { return (selector1->UID == selector2->UID); } void objc_unregisterAllSelectors(void) { objc_hashtable_free(selectors); objc_sparsearray_free(selectorNames); if (freeList != NULL) { for (size_t i = 0; i < freeListCount; i++) free(freeList[i]); |
︙ | ︙ |
Modified src/runtime/sparsearray.m from [454092d9a3] to [5acb08c6c8].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #include <stdio.h> #include <stdlib.h> #import "ObjFWRT.h" #import "private.h" struct objc_sparsearray * | | | < < | | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #include <stdio.h> #include <stdlib.h> #import "ObjFWRT.h" #import "private.h" struct objc_sparsearray * objc_sparsearray_new(uint8_t levels) { struct objc_sparsearray *sparsearray; if ((sparsearray = calloc(1, sizeof(*sparsearray))) == NULL || (sparsearray->data = calloc(1, sizeof(*sparsearray->data))) == NULL) OBJC_ERROR("Failed to allocate memory for sparse array!"); sparsearray->levels = levels; return sparsearray; } void * objc_sparsearray_get(struct objc_sparsearray *sparsearray, uintptr_t idx) { struct objc_sparsearray_data *iter = sparsearray->data; for (uint8_t i = 0; i < sparsearray->levels - 1; i++) { uintptr_t j = (idx >> ((sparsearray->levels - i - 1) * 8)) & 0xFF; if ((iter = iter->next[j]) == NULL) return NULL; } return iter->next[idx & 0xFF]; } void objc_sparsearray_set(struct objc_sparsearray *sparsearray, uintptr_t idx, void *value) { struct objc_sparsearray_data *iter = sparsearray->data; for (uint8_t i = 0; i < sparsearray->levels - 1; i++) { uintptr_t j = (idx >> ((sparsearray->levels - i - 1) * 8)) & 0xFF; if (iter->next[j] == NULL) if ((iter->next[j] = calloc(1, sizeof(struct objc_sparsearray_data))) == NULL) OBJC_ERROR("Failed to allocate memory for " "sparse array!"); |
︙ | ︙ | |||
88 89 90 91 92 93 94 | free(data); } void objc_sparsearray_free(struct objc_sparsearray *sparsearray) { | | | 84 85 86 87 88 89 90 91 92 93 | free(data); } void objc_sparsearray_free(struct objc_sparsearray *sparsearray) { freeSparsearrayData(sparsearray->data, sparsearray->levels); free(sparsearray); } |
Modified src/runtime/static-instances.m from [314b61ed5d] to [a4b6846d46].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | #import "ObjFWRT.h" #import "private.h" static struct objc_static_instances **staticInstancesList = NULL; static size_t staticInstancesCount = 0; void | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #import "ObjFWRT.h" #import "private.h" static struct objc_static_instances **staticInstancesList = NULL; static size_t staticInstancesCount = 0; void objc_initStaticInstances(struct objc_symtab *symtab) { struct objc_static_instances **staticInstances; /* Check if the class for a static instance became available */ for (size_t i = 0; i < staticInstancesCount; i++) { Class class = objc_lookUpClass( staticInstancesList[i]->className); |
︙ | ︙ | |||
93 94 95 96 97 98 99 | staticInstancesList[staticInstancesCount++] = *staticInstances; } } } void | | | 91 92 93 94 95 96 97 98 99 100 101 102 103 | staticInstancesList[staticInstancesCount++] = *staticInstances; } } } void objc_forgetPendingStaticInstances() { free(staticInstancesList); staticInstancesList = NULL; staticInstancesCount = 0; } |
Modified src/runtime/synchronized.m from [dcf43cf9c5] to [2eb69df2c4].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #include <stdio.h> #include <stdlib.h> #import "ObjFWRT.h" #import "private.h" #ifdef OF_HAVE_THREADS | | | | | | | | | | | | | | | | | | | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | #include <stdio.h> #include <stdlib.h> #import "ObjFWRT.h" #import "private.h" #ifdef OF_HAVE_THREADS # import "OFPlainMutex.h" static struct Lock { id object; int count; OFPlainRecursiveMutex rmutex; struct Lock *next; } *locks = NULL; static OFPlainMutex mutex; OF_CONSTRUCTOR() { if (OFPlainMutexNew(&mutex) != 0) OBJC_ERROR("Failed to create mutex!"); } #endif int objc_sync_enter(id object) { if (object == nil) return 0; #ifdef OF_HAVE_THREADS struct Lock *lock; if (OFPlainMutexLock(&mutex) != 0) OBJC_ERROR("Failed to lock mutex!"); /* Look if we already have a lock */ for (lock = locks; lock != NULL; lock = lock->next) { if (lock->object != object) continue; lock->count++; if (OFPlainMutexUnlock(&mutex) != 0) OBJC_ERROR("Failed to unlock mutex!"); if (OFPlainRecursiveMutexLock(&lock->rmutex) != 0) OBJC_ERROR("Failed to lock mutex!"); return 0; } /* Create a new lock */ if ((lock = malloc(sizeof(*lock))) == NULL) OBJC_ERROR("Failed to allocate memory for mutex!"); if (OFPlainRecursiveMutexNew(&lock->rmutex) != 0) OBJC_ERROR("Failed to create mutex!"); lock->object = object; lock->count = 1; lock->next = locks; locks = lock; if (OFPlainMutexUnlock(&mutex) != 0) OBJC_ERROR("Failed to unlock mutex!"); if (OFPlainRecursiveMutexLock(&lock->rmutex) != 0) OBJC_ERROR("Failed to lock mutex!"); #endif return 0; } int objc_sync_exit(id object) { if (object == nil) return 0; #ifdef OF_HAVE_THREADS struct Lock *lock, *last = NULL; if (OFPlainMutexLock(&mutex) != 0) OBJC_ERROR("Failed to lock mutex!"); for (lock = locks; lock != NULL; lock = lock->next) { if (lock->object != object) { last = lock; continue; } if (OFPlainRecursiveMutexUnlock(&lock->rmutex) != 0) OBJC_ERROR("Failed to unlock mutex!"); if (--lock->count == 0) { if (OFPlainRecursiveMutexFree(&lock->rmutex) != 0) OBJC_ERROR("Failed to destroy mutex!"); if (last != NULL) last->next = lock->next; if (locks == lock) locks = lock->next; free(lock); } if (OFPlainMutexUnlock(&mutex) != 0) OBJC_ERROR("Failed to unlock mutex!"); return 0; } OBJC_ERROR("objc_sync_exit() was called for an unlocked object!"); #else return 0; #endif } |
Modified src/runtime/tagged-pointer.m from [347f048030] to [747427397b].
1 | /* | < < | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "ObjFWRT.h" #import "private.h" #define numTaggedPointerBits 4 #define maxNumTaggedPointerClasses (1 << (numTaggedPointerBits - 1)) Class objc_taggedPointerClasses[maxNumTaggedPointerClasses]; static int taggedPointerClassesCount; uintptr_t objc_taggedPointerSecret; void objc_setTaggedPointerSecret(uintptr_t secret) { objc_taggedPointerSecret = secret & ~(uintptr_t)1; } int objc_registerTaggedPointerClass(Class class) { int i; objc_globalMutex_lock(); if (taggedPointerClassesCount == maxNumTaggedPointerClasses) { objc_globalMutex_unlock(); return -1; } i = taggedPointerClassesCount++; objc_taggedPointerClasses[i] = class; objc_globalMutex_unlock(); return i; } bool object_isTaggedPointer(id object) { uintptr_t pointer = (uintptr_t)object; return pointer & 1; } Class object_getTaggedPointerClass(id object) { uintptr_t pointer = (uintptr_t)object ^ objc_taggedPointerSecret; pointer &= (1 << numTaggedPointerBits) - 1; pointer >>= 1; if (pointer >= maxNumTaggedPointerClasses) return Nil; return objc_taggedPointerClasses[pointer]; } uintptr_t object_getTaggedPointerValue(id object) { uintptr_t pointer = (uintptr_t)object ^ objc_taggedPointerSecret; pointer >>= numTaggedPointerBits; return pointer; } id objc_createTaggedPointer(int class, uintptr_t value) { uintptr_t pointer; if (class < 0 || class >= maxNumTaggedPointerClasses) return nil; if (value > (UINTPTR_MAX >> numTaggedPointerBits)) return nil; pointer = (class << 1) | 1; pointer |= (value << numTaggedPointerBits); return (id)(pointer ^ objc_taggedPointerSecret); } |
Modified src/runtime/threading.m from [e792c643b3] to [f4000ae0f7].
1 | /* | < < | > | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #import "ObjFWRT.h" #import "private.h" #import "OFOnce.h" #import "OFPlainMutex.h" static OFPlainRecursiveMutex globalMutex; static void init(void) { if (OFPlainRecursiveMutexNew(&globalMutex) != 0) OBJC_ERROR("Failed to create global mutex!"); } void objc_globalMutex_lock(void) { static OFOnceControl onceControl = OFOnceControlInitValue; OFOnce(&onceControl, init); if (OFPlainRecursiveMutexLock(&globalMutex) != 0) OBJC_ERROR("Failed to lock global mutex!"); } void objc_globalMutex_unlock(void) { if (OFPlainRecursiveMutexUnlock(&globalMutex) != 0) OBJC_ERROR("Failed to unlock global mutex!"); } |
Added src/tls/Info.plist.in version [06bf405764].
> > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleExecutable</key> <string>ObjFWTLS</string> <key>CFBundleName</key> <string>ObjFWTLS</string> <key>CFBundleIdentifier</key> <string>im.nil.objfw.tls</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundlePackageType</key> <string>FMWK</string> <key>CFBundleVersion</key> <string>@BUNDLE_VERSION@</string> <key>CFBundleShortVersionString</key> <string>@BUNDLE_SHORT_VERSION@</string> <key>MinimumOSVersion</key> <string>9.0</string> </dict> </plist> |
Added src/tls/Makefile version [a6c2c67827].
> > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | include ../../extra.mk DISTCLEAN = Info.plist SHARED_LIB = ${OBJFWTLS_SHARED_LIB} STATIC_LIB = ${OBJFWTLS_STATIC_LIB} FRAMEWORK = ${OBJFWTLS_FRAMEWORK} LIB_MAJOR = ${OBJFW_LIB_MAJOR} LIB_MINOR = ${OBJFW_LIB_MINOR} INCLUDES := ObjFWTLS.h SRCS = ${OF_GNUTLS_TLS_STREAM_M} \ ${OF_OPENSSL_TLS_STREAM_M} \ ${OF_SECURE_TRANSPORT_TLS_STREAM_M} includesubdir = ObjFWTLS include ../../buildsys.mk CPPFLAGS += -I. -I.. -I../.. -I../exceptions -I../runtime ${TLS_CPPFLAGS} LD = ${OBJC} FRAMEWORK_LIBS := ${TLS_LIBS} -F.. -framework ObjFW ${LIBS} LIBS := ${TLS_LIBS} -L.. -lobjfw -L../runtime ${RUNTIME_LIBS} ${LIBS} |
Added src/tls/OFGnuTLSTLSStream.h version [d33b11b9cb].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFTLSStream.h" #include <gnutls/gnutls.h> OF_ASSUME_NONNULL_BEGIN @interface OFGnuTLSTLSStream: OFTLSStream <OFStreamDelegate> { bool _initialized, _handshakeDone; gnutls_session_t _session; OFString *_host; } @end OF_ASSUME_NONNULL_END |
Added src/tls/OFGnuTLSTLSStream.m version [fad8797bf6].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFGnuTLSTLSStream.h" #import "OFData.h" #import "OFAlreadyConnectedException.h" #import "OFInitializationFailedException.h" #import "OFNotOpenException.h" #import "OFReadFailedException.h" #import "OFTLSHandshakeFailedException.h" #import "OFWriteFailedException.h" int _ObjFWTLS_reference; static gnutls_certificate_credentials_t systemTrustCreds; #ifndef GNUTLS_SAFE_PADDING_CHECK /* Some older versions don't have it. */ # define GNUTLS_SAFE_PADDING_CHECK 0 #endif @implementation OFGnuTLSTLSStream static ssize_t readFunc(gnutls_transport_ptr_t transport, void *buffer, size_t length) { OFGnuTLSTLSStream *stream = (OFGnuTLSTLSStream *)transport; @try { length = [stream.underlyingStream readIntoBuffer: buffer length: length]; } @catch (OFReadFailedException *e) { gnutls_transport_set_errno(stream->_session, e.errNo); return -1; } if (length == 0 && !stream.underlyingStream.atEndOfStream) { gnutls_transport_set_errno(stream->_session, EAGAIN); return -1; } return length; } static ssize_t writeFunc(gnutls_transport_ptr_t transport, const void *buffer, size_t length) { OFGnuTLSTLSStream *stream = (OFGnuTLSTLSStream *)transport; @try { [stream.underlyingStream writeBuffer: buffer length: length]; } @catch (OFWriteFailedException *e) { gnutls_transport_set_errno(stream->_session, e.errNo); if (e.errNo == EWOULDBLOCK || e.errNo == EAGAIN) return e.bytesWritten; return -1; } return length; } + (void)load { if (OFTLSStreamImplementation == Nil) OFTLSStreamImplementation = self; } + (void)initialize { if (self != [OFGnuTLSTLSStream class]) return; if (gnutls_certificate_allocate_credentials(&systemTrustCreds) != GNUTLS_E_SUCCESS || gnutls_certificate_set_x509_system_trust(systemTrustCreds) < 0) @throw [OFInitializationFailedException exception]; } - (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream { self = [super initWithStream: stream]; @try { _underlyingStream.delegate = self; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_initialized) [self close]; [_host release]; [super dealloc]; } - (void)close { if (!_initialized) @throw [OFNotOpenException exceptionWithObject: self]; if (_handshakeDone) gnutls_bye(_session, GNUTLS_SHUT_WR); gnutls_deinit(_session); _initialized = false; [_host release]; _host = nil; [super close]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { ssize_t ret; if (!_handshakeDone) @throw [OFNotOpenException exceptionWithObject: self]; if ((ret = gnutls_record_recv(_session, buffer, length)) < 0) { /* * The underlying stream might have had data ready, but not * enough for GnuTLS to return decrypted data. This means the * caller might have observed the TLS stream for reading, got a * ready signal and read - and expects the read to succeed, not * to fail with EWOULDBLOCK/EAGAIN, as it was signaled ready. * Therefore, return 0, as we could read 0 decrypted bytes, but * cleared the ready signal of the underlying stream. */ if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) return 0; /* FIXME: Translate error to errNo */ @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: 0]; } return ret; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { ssize_t ret; if (!_handshakeDone) @throw [OFNotOpenException exceptionWithObject: self]; if ((ret = gnutls_record_send(_session, buffer, length)) < 0) { if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) return 0; /* FIXME: Translate error to errNo */ @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: ret errNo: 0]; } return ret; } - (bool)hasDataInReadBuffer { if (gnutls_record_check_pending(_session) > 0) return true; return super.hasDataInReadBuffer; } - (void)asyncPerformClientHandshakeWithHost: (OFString *)host runLoopMode: (OFRunLoopMode)runLoopMode { static const OFTLSStreamErrorCode initFailedErrorCode = OFTLSStreamErrorCodeInitializationFailed; id exception = nil; int status; if (_initialized) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if (gnutls_init(&_session, GNUTLS_CLIENT | GNUTLS_NONBLOCK | GNUTLS_SAFE_PADDING_CHECK) != GNUTLS_E_SUCCESS) @throw [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: initFailedErrorCode]; _initialized = true; gnutls_transport_set_ptr(_session, self); gnutls_transport_set_pull_function(_session, readFunc); gnutls_transport_set_push_function(_session, writeFunc); if (gnutls_set_default_priority(_session) != GNUTLS_E_SUCCESS || gnutls_credentials_set(_session, GNUTLS_CRD_CERTIFICATE, systemTrustCreds) != GNUTLS_E_SUCCESS) @throw [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: initFailedErrorCode]; _host = [host copy]; if (gnutls_server_name_set(_session, GNUTLS_NAME_DNS, _host.UTF8String, _host.UTF8StringLength) != GNUTLS_E_SUCCESS) @throw [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: initFailedErrorCode]; if (_verifiesCertificates) gnutls_session_set_verify_cert(_session, _host.UTF8String, 0); status = gnutls_handshake(_session); if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(_session) == 1) [_underlyingStream asyncWriteData: [OFData dataWithItems: "" count: 0] runLoopMode: runLoopMode]; else [_underlyingStream asyncReadIntoBuffer: (void *)"" length: 0 runLoopMode: runLoopMode]; [_delegate retain]; return; } if (status == GNUTLS_E_SUCCESS) _handshakeDone = true; else /* FIXME: Map to better errors */ exception = [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: OFTLSStreamErrorCodeUnknown]; if ([_delegate respondsToSelector: @selector(stream:didPerformClientHandshakeWithHost:exception:)]) [_delegate stream: self didPerformClientHandshakeWithHost: host exception: exception]; } - (bool)stream: (OFStream *)stream didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (nullable id)exception { if (exception == nil) { int status = gnutls_handshake(_session); if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(_session) == 1) { OFData *data = [OFData dataWithItems: "" count: 0]; OFRunLoopMode runLoopMode = [OFRunLoop currentRunLoop].currentMode; [_underlyingStream asyncWriteData: data runLoopMode: runLoopMode]; return false; } else return true; } if (status == GNUTLS_E_SUCCESS) _handshakeDone = true; else exception = [OFTLSHandshakeFailedException exceptionWithStream: self host: _host errorCode: OFTLSStreamErrorCodeUnknown]; } if ([_delegate respondsToSelector: @selector(stream:didPerformClientHandshakeWithHost:exception:)]) [_delegate stream: self didPerformClientHandshakeWithHost: _host exception: exception]; [_delegate release]; return false; } - (OFData *)stream: (OFStream *)stream didWriteData: (OFData *)data bytesWritten: (size_t)bytesWritten exception: (id)exception { if (exception == nil) { int status = gnutls_handshake(_session); if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(_session) == 1) return data; else { OFRunLoopMode runLoopMode = [OFRunLoop currentRunLoop].currentMode; [_underlyingStream asyncReadIntoBuffer: (void *)"" length: 0 runLoopMode: runLoopMode]; return nil; } } if (status == GNUTLS_E_SUCCESS) _handshakeDone = true; else exception = [OFTLSHandshakeFailedException exceptionWithStream: self host: _host errorCode: OFTLSStreamErrorCodeUnknown]; } if ([_delegate respondsToSelector: @selector(stream:didPerformClientHandshakeWithHost:exception:)]) [_delegate stream: self didPerformClientHandshakeWithHost: _host exception: exception]; [_delegate release]; return nil; } @end |
Added src/tls/OFOpenSSLTLSStream.h version [5bdb0a26b6].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFTLSStream.h" #include <openssl/bio.h> #include <openssl/ssl.h> OF_ASSUME_NONNULL_BEGIN #define OFOpenSSLTLSStreamBufferSize 512 @interface OFOpenSSLTLSStream: OFTLSStream <OFStreamDelegate> { bool _handshakeDone; SSL *_SSL; BIO *_readBIO, *_writeBIO; OFString *_host; char _buffer[OFOpenSSLTLSStreamBufferSize]; } @end OF_ASSUME_NONNULL_END |
Added src/tls/OFOpenSSLTLSStream.m version [f8706b398d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFOpenSSLTLSStream.h" #import "OFData.h" #import "OFAlreadyConnectedException.h" #import "OFInitializationFailedException.h" #import "OFNotOpenException.h" #import "OFReadFailedException.h" #import "OFTLSHandshakeFailedException.h" #import "OFWriteFailedException.h" #define bufferSize OFOpenSSLTLSStreamBufferSize int _ObjFWTLS_reference; static SSL_CTX *clientContext; @implementation OFOpenSSLTLSStream + (void)load { if (OFTLSStreamImplementation == Nil) OFTLSStreamImplementation = self; } + (void)initialize { if (self != [OFOpenSSLTLSStream class]) return; SSL_load_error_strings(); SSL_library_init(); if ((clientContext = SSL_CTX_new(TLS_client_method())) == NULL || SSL_CTX_set_default_verify_paths(clientContext) != 1) @throw [OFInitializationFailedException exceptionWithClass: self]; } - (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream { self = [super initWithStream: stream]; @try { _underlyingStream.delegate = self; /* * Buffer writes so that nothing gets lost if we write more * than the underlying stream can write. */ _underlyingStream.buffersWrites = true; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_SSL != NULL) [self close]; [_host release]; [super dealloc]; } - (void)close { if (_SSL == NULL) @throw [OFNotOpenException exceptionWithObject: self]; if (_handshakeDone) SSL_shutdown(_SSL); SSL_free(_SSL); _SSL = NULL; [_host release]; _host = nil; [super close]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { int ret; size_t bytesRead; if (!_handshakeDone) @throw [OFNotOpenException exceptionWithObject: self]; if (BIO_ctrl_pending(_readBIO) < 1) { @try { size_t tmp = [_underlyingStream readIntoBuffer: _buffer length: bufferSize]; OFEnsure(tmp <= INT_MAX); /* Writing to a memory BIO must never fail. */ OFEnsure(BIO_write(_readBIO, _buffer, (int)tmp) == (int)tmp); } @catch (OFReadFailedException *e) { if (e.errNo != EWOULDBLOCK && e.errNo != EAGAIN) @throw e; } } ret = SSL_read_ex(_SSL, buffer, length, &bytesRead); while (BIO_ctrl_pending(_writeBIO) > 0) { int tmp = BIO_read(_writeBIO, _buffer, bufferSize); OFEnsure(tmp >= 0); [_underlyingStream writeBuffer: _buffer length: tmp]; [_underlyingStream flushWriteBuffer]; } if (ret != 1) { /* * The underlying stream might have had data ready, but not * enough for OpenSSL to return decrypted data. This means the * caller might have observed the TLS stream for reading, got a * ready signal and read - and expects the read to succeed, not * to fail with EWOULDBLOCK, as it was signaled ready. * Therefore, return 0, as we could read 0 decrypted bytes, but * cleared the ready signal of the underlying stream. */ if (SSL_get_error(_SSL, ret) == SSL_ERROR_WANT_READ) return 0; /* FIXME: Translate error to errNo */ @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: 0]; } return bytesRead; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { int ret; size_t bytesWritten; if (!_handshakeDone) @throw [OFNotOpenException exceptionWithObject: self]; if ((ret = SSL_write_ex(_SSL, buffer, length, &bytesWritten)) != 1) { /* FIXME: Translate error to errNo */ int errNo = 0; if (SSL_get_error(_SSL, ret) == SSL_ERROR_WANT_WRITE) return bytesWritten; @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: errNo]; } while (BIO_ctrl_pending(_writeBIO) > 0) { int tmp = BIO_read(_writeBIO, _buffer, bufferSize); OFEnsure(tmp >= 0); [_underlyingStream writeBuffer: _buffer length: tmp]; [_underlyingStream flushWriteBuffer]; } return bytesWritten; } - (bool)hasDataInReadBuffer { if (SSL_has_pending(_SSL) || BIO_ctrl_pending(_readBIO) > 0) return true; return super.hasDataInReadBuffer; } - (void)asyncPerformClientHandshakeWithHost: (OFString *)host runLoopMode: (OFRunLoopMode)runLoopMode { static const OFTLSStreamErrorCode initFailedErrorCode = OFTLSStreamErrorCodeInitializationFailed; id exception = nil; int status; if (_SSL != NULL) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; if ((_readBIO = BIO_new(BIO_s_mem())) == NULL) @throw [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: initFailedErrorCode]; if ((_writeBIO = BIO_new(BIO_s_mem())) == NULL) { BIO_free(_readBIO); @throw [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: initFailedErrorCode]; } BIO_set_mem_eof_return(_readBIO, -1); BIO_set_mem_eof_return(_writeBIO, -1); if ((_SSL = SSL_new(clientContext)) == NULL) { BIO_free(_readBIO); BIO_free(_writeBIO); @throw [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: initFailedErrorCode]; } SSL_set_bio(_SSL, _readBIO, _writeBIO); SSL_set_connect_state(_SSL); _host = [host copy]; if (SSL_set_tlsext_host_name(_SSL, _host.UTF8String) != 1) @throw [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: initFailedErrorCode]; if (_verifiesCertificates) { SSL_set_verify(_SSL, SSL_VERIFY_PEER, NULL); if (SSL_set1_host(_SSL, _host.UTF8String) != 1) @throw [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: initFailedErrorCode]; } status = SSL_do_handshake(_SSL); while (BIO_ctrl_pending(_writeBIO) > 0) { int tmp = BIO_read(_writeBIO, _buffer, bufferSize); OFEnsure(tmp >= 0); [_underlyingStream writeBuffer: _buffer length: tmp]; [_underlyingStream flushWriteBuffer]; } if (status == 1) _handshakeDone = true; else { switch (SSL_get_error(_SSL, status)) { case SSL_ERROR_WANT_READ: [_underlyingStream asyncReadIntoBuffer: _buffer length: bufferSize runLoopMode: runLoopMode]; [_delegate retain]; return; case SSL_ERROR_WANT_WRITE: [_underlyingStream asyncWriteData: [OFData dataWithItems: "" count: 0] runLoopMode: runLoopMode]; [_delegate retain]; return; default: /* FIXME: Map to better errors */ exception = [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: OFTLSStreamErrorCodeUnknown]; break; } } if ([_delegate respondsToSelector: @selector(stream:didPerformClientHandshakeWithHost:exception:)]) [_delegate stream: self didPerformClientHandshakeWithHost: host exception: exception]; } - (bool)stream: (OFStream *)stream didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (nullable id)exception { if (exception == nil) { static const OFTLSStreamErrorCode unknownErrorCode = OFTLSStreamErrorCodeUnknown; int status; OFData *data; OFEnsure(length <= INT_MAX); OFEnsure(BIO_write(_readBIO, buffer, (int)length) == (int)length); status = SSL_do_handshake(_SSL); while (BIO_ctrl_pending(_writeBIO) > 0) { int tmp = BIO_read(_writeBIO, buffer, bufferSize); OFEnsure(tmp >= 0); [_underlyingStream writeBuffer: _buffer length: tmp]; [_underlyingStream flushWriteBuffer]; } if (status == 1) _handshakeDone = true; else { switch (SSL_get_error(_SSL, status)) { case SSL_ERROR_WANT_READ: return true; case SSL_ERROR_WANT_WRITE: data = [OFData dataWithItems: "" count: 0]; OFRunLoopMode runLoopMode = [OFRunLoop currentRunLoop].currentMode; [_underlyingStream asyncWriteData: data runLoopMode: runLoopMode]; return false; default: exception = [OFTLSHandshakeFailedException exceptionWithStream: self host: _host errorCode: unknownErrorCode]; break; } } } if ([_delegate respondsToSelector: @selector(stream:didPerformClientHandshakeWithHost:exception:)]) [_delegate stream: self didPerformClientHandshakeWithHost: _host exception: exception]; [_delegate release]; return false; } - (OFData *)stream: (OFStream *)stream didWriteData: (OFData *)data bytesWritten: (size_t)bytesWritten exception: (id)exception { if (exception == nil) { static const OFTLSStreamErrorCode unknownErrorCode = OFTLSStreamErrorCodeUnknown; int status; OFRunLoopMode runLoopMode; while (BIO_ctrl_pending(_writeBIO) > 0) { int tmp = BIO_read(_writeBIO, _buffer, bufferSize); OFEnsure(tmp >= 0); [_underlyingStream writeBuffer: _buffer length: tmp]; [_underlyingStream flushWriteBuffer]; } status = SSL_do_handshake(_SSL); while (BIO_ctrl_pending(_writeBIO) > 0) { int tmp = BIO_read(_writeBIO, _buffer, bufferSize); OFEnsure(tmp >= 0); [_underlyingStream writeBuffer: _buffer length: tmp]; [_underlyingStream flushWriteBuffer]; } if (status == 1) _handshakeDone = true; else { switch (SSL_get_error(_SSL, status)) { case SSL_ERROR_WANT_READ: runLoopMode = [OFRunLoop currentRunLoop].currentMode; [_underlyingStream asyncReadIntoBuffer: _buffer length: bufferSize runLoopMode: runLoopMode]; return nil; case SSL_ERROR_WANT_WRITE: return data; default: exception = [OFTLSHandshakeFailedException exceptionWithStream: self host: _host errorCode: unknownErrorCode]; break; } } } if ([_delegate respondsToSelector: @selector(stream:didPerformClientHandshakeWithHost:exception:)]) [_delegate stream: self didPerformClientHandshakeWithHost: _host exception: exception]; [_delegate release]; return nil; } @end |
Added src/tls/OFSecureTransportTLSStream.h version [6f1a3f10c3].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFTLSStream.h" #include <Security/SecureTransport.h> OF_ASSUME_NONNULL_BEGIN @interface OFSecureTransportTLSStream: OFTLSStream <OFStreamDelegate> { SSLContextRef _context; OFString *_host; } @end OF_ASSUME_NONNULL_END |
Added src/tls/OFSecureTransportTLSStream.m version [d93ffbbd51].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "OFSecureTransportTLSStream.h" #import "OFAlreadyConnectedException.h" #import "OFNotOpenException.h" #import "OFReadFailedException.h" #import "OFTLSHandshakeFailedException.h" #import "OFWriteFailedException.h" int _ObjFWTLS_reference; static OSStatus readFunc(SSLConnectionRef connection, void *data, size_t *dataLength) { bool incomplete; size_t length; @try { length = [((OFTLSStream *)connection).underlyingStream readIntoBuffer: data length: *dataLength]; } @catch (OFReadFailedException *e) { if (e.errNo == EWOULDBLOCK || e.errNo == EAGAIN) { *dataLength = 0; return errSSLWouldBlock; } @throw e; } incomplete = (length < *dataLength); *dataLength = length; return (incomplete ? errSSLWouldBlock : noErr); } static OSStatus writeFunc(SSLConnectionRef connection, const void *data, size_t *dataLength) { @try { [((OFTLSStream *)connection).underlyingStream writeBuffer: data length: *dataLength]; } @catch (OFWriteFailedException *e) { *dataLength = e.bytesWritten; if (e.errNo == EWOULDBLOCK || e.errNo == EAGAIN) return errSSLWouldBlock; @throw e; } return noErr; } /* * Apple deprecated Secure Transport without providing a replacement that can * work with any socket. On top of that, their replacement, Network.framework, * doesn't support STARTTLS at all. */ #if OF_GCC_VERSION >= 402 # pragma GCC diagnostic ignored "-Wdeprecated" #endif @implementation OFSecureTransportTLSStream + (void)load { if (OFTLSStreamImplementation == Nil) OFTLSStreamImplementation = self; } - (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving, OFReadyForWritingObserving> *)stream { self = [super initWithStream: stream]; @try { _underlyingStream.delegate = self; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { if (_context != NULL) [self close]; [_host release]; [super dealloc]; } - (void)close { if (_context == NULL) @throw [OFNotOpenException exceptionWithObject: self]; [_host release]; _host = nil; SSLClose(_context); #ifdef HAVE_SSLCREATECONTEXT CFRelease(_context); #else SSLDisposeContext(_context); #endif _context = NULL; [super close]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length { OSStatus status; size_t ret; if (_context == NULL) @throw [OFNotOpenException exceptionWithObject: self]; status = SSLRead(_context, buffer, length, &ret); if (status != noErr && status != errSSLWouldBlock) /* FIXME: Translate status to errNo */ @throw [OFReadFailedException exceptionWithObject: self requestedLength: length errNo: 0]; return ret; } - (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length { OSStatus status; size_t bytesWritten = 0; if (_context == NULL) @throw [OFNotOpenException exceptionWithObject: self]; status = SSLWrite(_context, buffer, length, &bytesWritten); if (status != noErr && status != errSSLWouldBlock) /* FIXME: Translate status to errNo */ @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; return bytesWritten; } - (bool)hasDataInReadBuffer { size_t bufferSize; if (SSLGetBufferedReadSize(_context, &bufferSize) == noErr && bufferSize > 0) return true; return super.hasDataInReadBuffer; } - (void)asyncPerformClientHandshakeWithHost: (OFString *)host runLoopMode: (OFRunLoopMode)runLoopMode { static const OFTLSStreamErrorCode initFailedErrorCode = OFTLSStreamErrorCodeInitializationFailed; id exception = nil; OSStatus status; if (_context != NULL) @throw [OFAlreadyConnectedException exceptionWithSocket: self]; #ifdef HAVE_SSLCREATECONTEXT if ((_context = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType)) == NULL) #else if (SSLNewContext(false, &_context) != noErr) #endif @throw [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: initFailedErrorCode]; if (SSLSetIOFuncs(_context, readFunc, writeFunc) != noErr || SSLSetConnection(_context, self) != noErr) @throw [OFTLSHandshakeFailedException exceptionWithStream: self host: host errorCode: initFailedErrorCode]; _host = [host copy]; if (_verifiesCertificates) if (SSLSetPeerDomainName(_context, _host.UTF8String, _host.UTF8StringLength) != noErr) @throw [OFTLSHandshakeFailedException exceptionWithStream: self host: _host errorCode: initFailedErrorCode]; status = SSLHandshake(_context); if (status == errSSLWouldBlock) { /* * Theoretically it is possible we block because Secure * Transport cannot write without blocking. But unfortunately, * Secure Transport does not tell us whether it's blocked on * reading or writing. Waiting for the stream to be either * readable or writable doesn't work either, as the stream is * almost always at least ready for one of the two. */ [_underlyingStream asyncReadIntoBuffer: (void *)"" length: 0 runLoopMode: runLoopMode]; [_delegate retain]; return; } if (status != noErr) /* FIXME: Map to better errors */ exception = [OFTLSHandshakeFailedException exceptionWithStream: self host: _host errorCode: OFTLSStreamErrorCodeUnknown]; if ([_delegate respondsToSelector: @selector(stream:didPerformClientHandshakeWithHost:exception:)]) [_delegate stream: self didPerformClientHandshakeWithHost: _host exception: exception]; } - (bool)stream: (OFStream *)stream didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (nullable id)exception { if (exception == nil) { OSStatus status = SSLHandshake(_context); if (status == errSSLWouldBlock) return true; if (status != noErr) exception = [OFTLSHandshakeFailedException exceptionWithStream: self host: _host errorCode: OFTLSStreamErrorCodeUnknown]; } if ([_delegate respondsToSelector: @selector(stream:didPerformClientHandshakeWithHost:exception:)]) [_delegate stream: self didPerformClientHandshakeWithHost: _host exception: exception]; [_delegate release]; return false; } @end |
Added src/tls/ObjFWTLS.h version [498108c5a2].
> > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "macros.h" #ifdef __cplusplus extern "C" { #endif extern int _ObjFWTLS_reference; #ifdef __cplusplus } #endif |
Modified src/unicode.h from [5f9cf58b43] to [2eea427f38].
1 | /* | < < | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFString.h" #define OFUnicodeUppercaseTableSize 0x1EA #define OFUnicodeLowercaseTableSize 0x1EA #define OFUnicodeTitlecaseTableSize 0x1EA #define OFUnicodeCaseFoldingTableSize 0x1EA #define OFUnicodeDecompositionTableSize 0x2FB #define OFUnicodeDecompositionCompatTableSize 0x2FB #ifdef __cplusplus extern "C" { #endif extern const OFUnichar *const _Nonnull OFUnicodeUppercaseTable[OFUnicodeUppercaseTableSize]; extern const OFUnichar *const _Nonnull OFUnicodeLowercaseTable[OFUnicodeLowercaseTableSize]; extern const OFUnichar *const _Nonnull OFUnicodeTitlecaseTable[OFUnicodeTitlecaseTableSize]; extern const OFUnichar *const _Nonnull OFUnicodeCaseFoldingTable[OFUnicodeCaseFoldingTableSize]; extern const char *const _Nullable *const _Nonnull OFUnicodeDecompositionTable[OFUnicodeDecompositionTableSize]; extern const char *const _Nullable *const _Nonnull OFUnicodeDecompositionCompatTable[OFUnicodeDecompositionCompatTableSize]; #ifdef __cplusplus } #endif |
Modified src/unicode.m from [8d99c0a504] to [1934fadafb].
1 | /* | < < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "OFString.h" static const OFUnichar emptyPage[0x100] = { 0 }; static const char *emptyDecompositionPage[0x100] = { NULL }; static const OFUnichar uppercasePage0[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
53 54 55 56 57 58 59 | 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 0, 216, 217, 218, 219, 220, 221, 222, 376, }; | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 0, 216, 217, 218, 219, 220, 221, 222, 376, }; static const OFUnichar uppercasePage1[0x100] = { 0, 256, 0, 258, 0, 260, 0, 262, 0, 264, 0, 266, 0, 268, 0, 270, 0, 272, 0, 274, 0, 276, 0, 278, 0, 280, 0, 282, 0, 284, 0, 286, 0, 288, 0, 290, 0, 292, 0, 294, 0, 296, 0, 298, 0, 300, 0, 302, 0, 73, 0, 306, 0, 308, 0, 310, |
︙ | ︙ | |||
88 89 90 91 92 93 94 | 471, 0, 473, 0, 475, 398, 0, 478, 0, 480, 0, 482, 0, 484, 0, 486, 0, 488, 0, 490, 0, 492, 0, 494, 0, 0, 497, 497, 0, 500, 0, 0, 0, 504, 0, 506, 0, 508, 0, 510, }; | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 471, 0, 473, 0, 475, 398, 0, 478, 0, 480, 0, 482, 0, 484, 0, 486, 0, 488, 0, 490, 0, 492, 0, 494, 0, 0, 497, 497, 0, 500, 0, 0, 0, 504, 0, 506, 0, 508, 0, 510, }; static const OFUnichar uppercasePage2[0x100] = { 0, 512, 0, 514, 0, 516, 0, 518, 0, 520, 0, 522, 0, 524, 0, 526, 0, 528, 0, 530, 0, 532, 0, 534, 0, 536, 0, 538, 0, 540, 0, 542, 0, 0, 0, 546, 0, 548, 0, 550, 0, 552, 0, 554, 0, 556, 0, 558, 0, 560, 0, 562, 0, 0, 0, 0, |
︙ | ︙ | |||
123 124 125 126 127 128 129 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage3[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
158 159 160 161 162 163 164 | 0, 984, 0, 986, 0, 988, 0, 990, 0, 992, 0, 994, 0, 996, 0, 998, 0, 1000, 0, 1002, 0, 1004, 0, 1006, 922, 929, 1017, 895, 0, 917, 0, 0, 1015, 0, 0, 1018, 0, 0, 0, 0, }; | | | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | 0, 984, 0, 986, 0, 988, 0, 990, 0, 992, 0, 994, 0, 996, 0, 998, 0, 1000, 0, 1002, 0, 1004, 0, 1006, 922, 929, 1017, 895, 0, 917, 0, 0, 1015, 0, 0, 1018, 0, 0, 0, 0, }; static const OFUnichar uppercasePage4[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, |
︙ | ︙ | |||
193 194 195 196 197 198 199 | 0, 1240, 0, 1242, 0, 1244, 0, 1246, 0, 1248, 0, 1250, 0, 1252, 0, 1254, 0, 1256, 0, 1258, 0, 1260, 0, 1262, 0, 1264, 0, 1266, 0, 1268, 0, 1270, 0, 1272, 0, 1274, 0, 1276, 0, 1278, }; | | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | 0, 1240, 0, 1242, 0, 1244, 0, 1246, 0, 1248, 0, 1250, 0, 1252, 0, 1254, 0, 1256, 0, 1258, 0, 1260, 0, 1262, 0, 1264, 0, 1266, 0, 1268, 0, 1270, 0, 1272, 0, 1274, 0, 1276, 0, 1278, }; static const OFUnichar uppercasePage5[0x100] = { 0, 1280, 0, 1282, 0, 1284, 0, 1286, 0, 1288, 0, 1290, 0, 1292, 0, 1294, 0, 1296, 0, 1298, 0, 1300, 0, 1302, 0, 1304, 0, 1306, 0, 1308, 0, 1310, 0, 1312, 0, 1314, 0, 1316, 0, 1318, 0, 1320, 0, 1322, 0, 1324, 0, 1326, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
228 229 230 231 232 233 234 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage16[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
263 264 265 266 267 268 269 | 7320, 7321, 7322, 7323, 7324, 7325, 7326, 7327, 7328, 7329, 7330, 7331, 7332, 7333, 7334, 7335, 7336, 7337, 7338, 7339, 7340, 7341, 7342, 7343, 7344, 7345, 7346, 7347, 7348, 7349, 7350, 7351, 7352, 7353, 7354, 0, 0, 7357, 7358, 7359, }; | | | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | 7320, 7321, 7322, 7323, 7324, 7325, 7326, 7327, 7328, 7329, 7330, 7331, 7332, 7333, 7334, 7335, 7336, 7337, 7338, 7339, 7340, 7341, 7342, 7343, 7344, 7345, 7346, 7347, 7348, 7349, 7350, 7351, 7352, 7353, 7354, 0, 0, 7357, 7358, 7359, }; static const OFUnichar uppercasePage19[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
298 299 300 301 302 303 304 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5104, 5105, 5106, 5107, 5108, 5109, 0, 0, }; | | | 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5104, 5105, 5106, 5107, 5108, 5109, 0, 0, }; static const OFUnichar uppercasePage28[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
333 334 335 336 337 338 339 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage29[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
368 369 370 371 372 373 374 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage30[0x100] = { 0, 7680, 0, 7682, 0, 7684, 0, 7686, 0, 7688, 0, 7690, 0, 7692, 0, 7694, 0, 7696, 0, 7698, 0, 7700, 0, 7702, 0, 7704, 0, 7706, 0, 7708, 0, 7710, 0, 7712, 0, 7714, 0, 7716, 0, 7718, 0, 7720, 0, 7722, 0, 7724, 0, 7726, 0, 7728, 0, 7730, 0, 7732, 0, 7734, |
︙ | ︙ | |||
403 404 405 406 407 408 409 | 0, 7896, 0, 7898, 0, 7900, 0, 7902, 0, 7904, 0, 7906, 0, 7908, 0, 7910, 0, 7912, 0, 7914, 0, 7916, 0, 7918, 0, 7920, 0, 7922, 0, 7924, 0, 7926, 0, 7928, 0, 7930, 0, 7932, 0, 7934, }; | | | 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 | 0, 7896, 0, 7898, 0, 7900, 0, 7902, 0, 7904, 0, 7906, 0, 7908, 0, 7910, 0, 7912, 0, 7914, 0, 7916, 0, 7918, 0, 7920, 0, 7922, 0, 7924, 0, 7926, 0, 7928, 0, 7930, 0, 7932, 0, 7934, }; static const OFUnichar uppercasePage31[0x100] = { 7944, 7945, 7946, 7947, 7948, 7949, 7950, 7951, 0, 0, 0, 0, 0, 0, 0, 0, 7960, 7961, 7962, 7963, 7964, 7965, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7976, 7977, 7978, 7979, 7980, 7981, 7982, 7983, 0, 0, 0, 0, 0, 0, 0, 0, 7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999, |
︙ | ︙ | |||
438 439 440 441 442 443 444 | 0, 0, 0, 0, 0, 0, 0, 0, 8168, 8169, 0, 0, 0, 8172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | 0, 0, 0, 0, 0, 0, 0, 0, 8168, 8169, 0, 0, 0, 8172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage33[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
473 474 475 476 477 478 479 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage36[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
508 509 510 511 512 513 514 | 9406, 9407, 9408, 9409, 9410, 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, 9420, 9421, 9422, 9423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 | 9406, 9407, 9408, 9409, 9410, 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, 9420, 9421, 9422, 9423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage44[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11264, 11265, 11266, 11267, 11268, 11269, 11270, 11271, |
︙ | ︙ | |||
543 544 545 546 547 548 549 | 0, 11480, 0, 11482, 0, 11484, 0, 11486, 0, 11488, 0, 11490, 0, 0, 0, 0, 0, 0, 0, 0, 11499, 0, 11501, 0, 0, 0, 0, 11506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 | 0, 11480, 0, 11482, 0, 11484, 0, 11486, 0, 11488, 0, 11490, 0, 0, 0, 0, 0, 0, 0, 0, 11499, 0, 11501, 0, 0, 0, 0, 11506, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage45[0x100] = { 4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287, 4288, 4289, 4290, 4291, 4292, 4293, 0, 4295, 0, 0, 0, 0, 0, 4301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
578 579 580 581 582 583 584 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage166[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
613 614 615 616 617 618 619 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage167[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42786, 0, 42788, 0, 42790, 0, 42792, 0, 42794, 0, 42796, 0, 42798, 0, 0, 0, 42802, 0, 42804, 0, 42806, |
︙ | ︙ | |||
648 649 650 651 652 653 654 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42997, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42997, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage171[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
683 684 685 686 687 688 689 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage255[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
718 719 720 721 722 723 724 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage260[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66560, 66561, 66562, 66563, 66564, 66565, 66566, 66567, 66568, 66569, 66570, 66571, 66572, 66573, 66574, 66575, |
︙ | ︙ | |||
753 754 755 756 757 758 759 | 66736, 66737, 66738, 66739, 66740, 66741, 66742, 66743, 66744, 66745, 66746, 66747, 66748, 66749, 66750, 66751, 66752, 66753, 66754, 66755, 66756, 66757, 66758, 66759, 66760, 66761, 66762, 66763, 66764, 66765, 66766, 66767, 66768, 66769, 66770, 66771, 0, 0, 0, 0, }; | | | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | 66736, 66737, 66738, 66739, 66740, 66741, 66742, 66743, 66744, 66745, 66746, 66747, 66748, 66749, 66750, 66751, 66752, 66753, 66754, 66755, 66756, 66757, 66758, 66759, 66760, 66761, 66762, 66763, 66764, 66765, 66766, 66767, 66768, 66769, 66770, 66771, 0, 0, 0, 0, }; static const OFUnichar uppercasePage268[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
788 789 790 791 792 793 794 | 68760, 68761, 68762, 68763, 68764, 68765, 68766, 68767, 68768, 68769, 68770, 68771, 68772, 68773, 68774, 68775, 68776, 68777, 68778, 68779, 68780, 68781, 68782, 68783, 68784, 68785, 68786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 | 68760, 68761, 68762, 68763, 68764, 68765, 68766, 68767, 68768, 68769, 68770, 68771, 68772, 68773, 68774, 68775, 68776, 68777, 68778, 68779, 68780, 68781, 68782, 68783, 68784, 68785, 68786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage280[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
823 824 825 826 827 828 829 | 71864, 71865, 71866, 71867, 71868, 71869, 71870, 71871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 | 71864, 71865, 71866, 71867, 71868, 71869, 71870, 71871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage366[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
858 859 860 861 862 863 864 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar uppercasePage489[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125184, 125185, 125186, 125187, 125188, 125189, 125190, 125191, 125192, 125193, 125194, 125195, 125196, 125197, 125198, 125199, 125200, 125201, 125202, 125203, 125204, 125205, |
︙ | ︙ | |||
893 894 895 896 897 898 899 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage0[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
928 929 930 931 932 933 934 | 248, 249, 250, 251, 252, 253, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 | 248, 249, 250, 251, 252, 253, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage1[0x100] = { 257, 0, 259, 0, 261, 0, 263, 0, 265, 0, 267, 0, 269, 0, 271, 0, 273, 0, 275, 0, 277, 0, 279, 0, 281, 0, 283, 0, 285, 0, 287, 0, 289, 0, 291, 0, 293, 0, 295, 0, 297, 0, 299, 0, 301, 0, 303, 0, 105, 0, 307, 0, 309, 0, 311, 0, |
︙ | ︙ | |||
963 964 965 966 967 968 969 | 0, 474, 0, 476, 0, 0, 479, 0, 481, 0, 483, 0, 485, 0, 487, 0, 489, 0, 491, 0, 493, 0, 495, 0, 0, 499, 499, 0, 501, 0, 405, 447, 505, 0, 507, 0, 509, 0, 511, 0, }; | | | 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 | 0, 474, 0, 476, 0, 0, 479, 0, 481, 0, 483, 0, 485, 0, 487, 0, 489, 0, 491, 0, 493, 0, 495, 0, 0, 499, 499, 0, 501, 0, 405, 447, 505, 0, 507, 0, 509, 0, 511, 0, }; static const OFUnichar lowercasePage2[0x100] = { 513, 0, 515, 0, 517, 0, 519, 0, 521, 0, 523, 0, 525, 0, 527, 0, 529, 0, 531, 0, 533, 0, 535, 0, 537, 0, 539, 0, 541, 0, 543, 0, 414, 0, 547, 0, 549, 0, 551, 0, 553, 0, 555, 0, 557, 0, 559, 0, 561, 0, 563, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
998 999 1000 1001 1002 1003 1004 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage3[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1033 1034 1035 1036 1037 1038 1039 | 985, 0, 987, 0, 989, 0, 991, 0, 993, 0, 995, 0, 997, 0, 999, 0, 1001, 0, 1003, 0, 1005, 0, 1007, 0, 0, 0, 0, 0, 952, 0, 0, 1016, 0, 1010, 1019, 0, 0, 891, 892, 893, }; | | | 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 | 985, 0, 987, 0, 989, 0, 991, 0, 993, 0, 995, 0, 997, 0, 999, 0, 1001, 0, 1003, 0, 1005, 0, 1007, 0, 0, 0, 0, 0, 952, 0, 0, 1016, 0, 1010, 1019, 0, 0, 891, 892, 893, }; static const OFUnichar lowercasePage4[0x100] = { 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1068 1069 1070 1071 1072 1073 1074 | 1241, 0, 1243, 0, 1245, 0, 1247, 0, 1249, 0, 1251, 0, 1253, 0, 1255, 0, 1257, 0, 1259, 0, 1261, 0, 1263, 0, 1265, 0, 1267, 0, 1269, 0, 1271, 0, 1273, 0, 1275, 0, 1277, 0, 1279, 0, }; | | | 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 | 1241, 0, 1243, 0, 1245, 0, 1247, 0, 1249, 0, 1251, 0, 1253, 0, 1255, 0, 1257, 0, 1259, 0, 1261, 0, 1263, 0, 1265, 0, 1267, 0, 1269, 0, 1271, 0, 1273, 0, 1275, 0, 1277, 0, 1279, 0, }; static const OFUnichar lowercasePage5[0x100] = { 1281, 0, 1283, 0, 1285, 0, 1287, 0, 1289, 0, 1291, 0, 1293, 0, 1295, 0, 1297, 0, 1299, 0, 1301, 0, 1303, 0, 1305, 0, 1307, 0, 1309, 0, 1311, 0, 1313, 0, 1315, 0, 1317, 0, 1319, 0, 1321, 0, 1323, 0, 1325, 0, 1327, 0, 0, 1377, 1378, 1379, 1380, 1381, 1382, 1383, |
︙ | ︙ | |||
1103 1104 1105 1106 1107 1108 1109 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage16[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1138 1139 1140 1141 1142 1143 1144 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage19[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1173 1174 1175 1176 1177 1178 1179 | 43944, 43945, 43946, 43947, 43948, 43949, 43950, 43951, 43952, 43953, 43954, 43955, 43956, 43957, 43958, 43959, 43960, 43961, 43962, 43963, 43964, 43965, 43966, 43967, 5112, 5113, 5114, 5115, 5116, 5117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 | 43944, 43945, 43946, 43947, 43948, 43949, 43950, 43951, 43952, 43953, 43954, 43955, 43956, 43957, 43958, 43959, 43960, 43961, 43962, 43963, 43964, 43965, 43966, 43967, 5112, 5113, 5114, 5115, 5116, 5117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage28[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1208 1209 1210 1211 1212 1213 1214 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage30[0x100] = { 7681, 0, 7683, 0, 7685, 0, 7687, 0, 7689, 0, 7691, 0, 7693, 0, 7695, 0, 7697, 0, 7699, 0, 7701, 0, 7703, 0, 7705, 0, 7707, 0, 7709, 0, 7711, 0, 7713, 0, 7715, 0, 7717, 0, 7719, 0, 7721, 0, 7723, 0, 7725, 0, 7727, 0, 7729, 0, 7731, 0, 7733, 0, 7735, 0, |
︙ | ︙ | |||
1243 1244 1245 1246 1247 1248 1249 | 7897, 0, 7899, 0, 7901, 0, 7903, 0, 7905, 0, 7907, 0, 7909, 0, 7911, 0, 7913, 0, 7915, 0, 7917, 0, 7919, 0, 7921, 0, 7923, 0, 7925, 0, 7927, 0, 7929, 0, 7931, 0, 7933, 0, 7935, 0, }; | | | 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 | 7897, 0, 7899, 0, 7901, 0, 7903, 0, 7905, 0, 7907, 0, 7909, 0, 7911, 0, 7913, 0, 7915, 0, 7917, 0, 7919, 0, 7921, 0, 7923, 0, 7925, 0, 7927, 0, 7929, 0, 7931, 0, 7933, 0, 7935, 0, }; static const OFUnichar lowercasePage31[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 0, 0, 0, 0, 0, 0, 0, 0, 7952, 7953, 7954, 7955, 7956, 7957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1278 1279 1280 1281 1282 1283 1284 | 8144, 8145, 8054, 8055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8160, 8161, 8058, 8059, 8165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8056, 8057, 8060, 8061, 8179, 0, 0, 0, }; | | | 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 | 8144, 8145, 8054, 8055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8160, 8161, 8058, 8059, 8165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8056, 8057, 8060, 8061, 8179, 0, 0, 0, }; static const OFUnichar lowercasePage33[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 969, 0, 0, 0, 107, 229, 0, 0, 0, 0, 0, 0, 8526, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1313 1314 1315 1316 1317 1318 1319 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage36[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1348 1349 1350 1351 1352 1353 1354 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage44[0x100] = { 11312, 11313, 11314, 11315, 11316, 11317, 11318, 11319, 11320, 11321, 11322, 11323, 11324, 11325, 11326, 11327, 11328, 11329, 11330, 11331, 11332, 11333, 11334, 11335, 11336, 11337, 11338, 11339, 11340, 11341, 11342, 11343, 11344, 11345, 11346, 11347, 11348, 11349, 11350, 11351, 11352, 11353, 11354, 11355, 11356, 11357, 11358, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1383 1384 1385 1386 1387 1388 1389 | 11481, 0, 11483, 0, 11485, 0, 11487, 0, 11489, 0, 11491, 0, 0, 0, 0, 0, 0, 0, 0, 11500, 0, 11502, 0, 0, 0, 0, 11507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 | 11481, 0, 11483, 0, 11485, 0, 11487, 0, 11489, 0, 11491, 0, 0, 0, 0, 0, 0, 0, 0, 11500, 0, 11502, 0, 0, 0, 0, 11507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage166[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1418 1419 1420 1421 1422 1423 1424 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage167[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42787, 0, 42789, 0, 42791, 0, 42793, 0, 42795, 0, 42797, 0, 42799, 0, 0, 0, 42803, 0, 42805, 0, 42807, 0, |
︙ | ︙ | |||
1453 1454 1455 1456 1457 1458 1459 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42998, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42998, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage255[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65345, 65346, 65347, 65348, 65349, 65350, 65351, 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359, 65360, 65361, 65362, 65363, 65364, 65365, 65366, 65367, |
︙ | ︙ | |||
1488 1489 1490 1491 1492 1493 1494 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage260[0x100] = { 66600, 66601, 66602, 66603, 66604, 66605, 66606, 66607, 66608, 66609, 66610, 66611, 66612, 66613, 66614, 66615, 66616, 66617, 66618, 66619, 66620, 66621, 66622, 66623, 66624, 66625, 66626, 66627, 66628, 66629, 66630, 66631, 66632, 66633, 66634, 66635, 66636, 66637, 66638, 66639, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1523 1524 1525 1526 1527 1528 1529 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage268[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1558 1559 1560 1561 1562 1563 1564 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage280[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1593 1594 1595 1596 1597 1598 1599 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage366[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1628 1629 1630 1631 1632 1633 1634 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar lowercasePage489[0x100] = { 125218, 125219, 125220, 125221, 125222, 125223, 125224, 125225, 125226, 125227, 125228, 125229, 125230, 125231, 125232, 125233, 125234, 125235, 125236, 125237, 125238, 125239, 125240, 125241, 125242, 125243, 125244, 125245, 125246, 125247, 125248, 125249, 125250, 125251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1663 1664 1665 1666 1667 1668 1669 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar titlecasePage1[0x100] = { 0, 256, 0, 258, 0, 260, 0, 262, 0, 264, 0, 266, 0, 268, 0, 270, 0, 272, 0, 274, 0, 276, 0, 278, 0, 280, 0, 282, 0, 284, 0, 286, 0, 288, 0, 290, 0, 292, 0, 294, 0, 296, 0, 298, 0, 300, 0, 302, 0, 73, 0, 306, 0, 308, 0, 310, |
︙ | ︙ | |||
1698 1699 1700 1701 1702 1703 1704 | 471, 0, 473, 0, 475, 398, 0, 478, 0, 480, 0, 482, 0, 484, 0, 486, 0, 488, 0, 490, 0, 492, 0, 494, 0, 498, 498, 498, 0, 500, 0, 0, 0, 504, 0, 506, 0, 508, 0, 510, }; | | | 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 | 471, 0, 473, 0, 475, 398, 0, 478, 0, 480, 0, 482, 0, 484, 0, 486, 0, 488, 0, 490, 0, 492, 0, 494, 0, 498, 498, 498, 0, 500, 0, 0, 0, 504, 0, 506, 0, 508, 0, 510, }; static const OFUnichar titlecasePage16[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1733 1734 1735 1736 1737 1738 1739 | 4312, 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329, 4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343, 4344, 4345, 4346, 0, 0, 4349, 4350, 4351, }; | | | 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 | 4312, 4313, 4314, 4315, 4316, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329, 4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343, 4344, 4345, 4346, 0, 0, 4349, 4350, 4351, }; static const OFUnichar caseFoldingPage0[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1768 1769 1770 1771 1772 1773 1774 | 248, 249, 250, 251, 252, 253, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 | 248, 249, 250, 251, 252, 253, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar caseFoldingPage1[0x100] = { 257, 0, 259, 0, 261, 0, 263, 0, 265, 0, 267, 0, 269, 0, 271, 0, 273, 0, 275, 0, 277, 0, 279, 0, 281, 0, 283, 0, 285, 0, 287, 0, 289, 0, 291, 0, 293, 0, 295, 0, 297, 0, 299, 0, 301, 0, 303, 0, 0, 0, 307, 0, 309, 0, 311, 0, |
︙ | ︙ | |||
1803 1804 1805 1806 1807 1808 1809 | 0, 474, 0, 476, 0, 0, 479, 0, 481, 0, 483, 0, 485, 0, 487, 0, 489, 0, 491, 0, 493, 0, 495, 0, 0, 499, 499, 0, 501, 0, 405, 447, 505, 0, 507, 0, 509, 0, 511, 0, }; | | | 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 | 0, 474, 0, 476, 0, 0, 479, 0, 481, 0, 483, 0, 485, 0, 487, 0, 489, 0, 491, 0, 493, 0, 495, 0, 0, 499, 499, 0, 501, 0, 405, 447, 505, 0, 507, 0, 509, 0, 511, 0, }; static const OFUnichar caseFoldingPage3[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1838 1839 1840 1841 1842 1843 1844 | 985, 0, 987, 0, 989, 0, 991, 0, 993, 0, 995, 0, 997, 0, 999, 0, 1001, 0, 1003, 0, 1005, 0, 1007, 0, 954, 961, 0, 0, 952, 949, 0, 1016, 0, 1010, 1019, 0, 0, 891, 892, 893, }; | | | 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 | 985, 0, 987, 0, 989, 0, 991, 0, 993, 0, 995, 0, 997, 0, 999, 0, 1001, 0, 1003, 0, 1005, 0, 1007, 0, 954, 961, 0, 0, 952, 949, 0, 1016, 0, 1010, 1019, 0, 0, 891, 892, 893, }; static const OFUnichar caseFoldingPage19[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1873 1874 1875 1876 1877 1878 1879 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5104, 5105, 5106, 5107, 5108, 5109, 0, 0, }; | | | 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5104, 5105, 5106, 5107, 5108, 5109, 0, 0, }; static const OFUnichar caseFoldingPage28[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1908 1909 1910 1911 1912 1913 1914 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; | | | 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const OFUnichar caseFoldingPage30[0x100] = { 7681, 0, 7683, 0, 7685, 0, 7687, 0, 7689, 0, 7691, 0, 7693, 0, 7695, 0, 7697, 0, 7699, 0, 7701, 0, 7703, 0, 7705, 0, 7707, 0, 7709, 0, 7711, 0, 7713, 0, 7715, 0, 7717, 0, 7719, 0, 7721, 0, 7723, 0, 7725, 0, 7727, 0, 7729, 0, 7731, 0, 7733, 0, 7735, 0, |
︙ | ︙ | |||
1943 1944 1945 1946 1947 1948 1949 | 7897, 0, 7899, 0, 7901, 0, 7903, 0, 7905, 0, 7907, 0, 7909, 0, 7911, 0, 7913, 0, 7915, 0, 7917, 0, 7919, 0, 7921, 0, 7923, 0, 7925, 0, 7927, 0, 7929, 0, 7931, 0, 7933, 0, 7935, 0, }; | | | 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 | 7897, 0, 7899, 0, 7901, 0, 7903, 0, 7905, 0, 7907, 0, 7909, 0, 7911, 0, 7913, 0, 7915, 0, 7917, 0, 7919, 0, 7921, 0, 7923, 0, 7925, 0, 7927, 0, 7929, 0, 7931, 0, 7933, 0, 7935, 0, }; static const OFUnichar caseFoldingPage31[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 0, 0, 0, 0, 0, 0, 0, 0, 7952, 7953, 7954, 7955, 7956, 7957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
1978 1979 1980 1981 1982 1983 1984 | 8144, 8145, 8054, 8055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8160, 8161, 8058, 8059, 8165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8056, 8057, 8060, 8061, 8179, 0, 0, 0, }; | | | 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 | 8144, 8145, 8054, 8055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8160, 8161, 8058, 8059, 8165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8056, 8057, 8060, 8061, 8179, 0, 0, 0, }; static const OFUnichar caseFoldingPage171[0x100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
12362 12363 12364 12365 12366 12367 12368 | "\x36", "\x37", "\x38", "\x39", NULL, NULL, NULL, NULL, NULL, NULL, }; | | | 12360 12361 12362 12363 12364 12365 12366 12367 12368 12369 12370 12371 12372 12373 12374 | "\x36", "\x37", "\x38", "\x39", NULL, NULL, NULL, NULL, NULL, NULL, }; const OFUnichar *const OFUnicodeUppercaseTable[0x1EA] = { uppercasePage0, uppercasePage1, uppercasePage2, uppercasePage3, uppercasePage4, uppercasePage5, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, uppercasePage16, emptyPage, emptyPage, uppercasePage19, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, |
︙ | ︙ | |||
12488 12489 12490 12491 12492 12493 12494 | emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, uppercasePage489 }; | | | 12486 12487 12488 12489 12490 12491 12492 12493 12494 12495 12496 12497 12498 12499 12500 | emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, uppercasePage489 }; const OFUnichar *const OFUnicodeLowercaseTable[0x1EA] = { lowercasePage0, lowercasePage1, lowercasePage2, lowercasePage3, lowercasePage4, lowercasePage5, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, lowercasePage16, emptyPage, emptyPage, lowercasePage19, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, |
︙ | ︙ | |||
12614 12615 12616 12617 12618 12619 12620 | emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, lowercasePage489 }; | | | 12612 12613 12614 12615 12616 12617 12618 12619 12620 12621 12622 12623 12624 12625 12626 | emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, lowercasePage489 }; const OFUnichar *const OFUnicodeTitlecaseTable[0x1EA] = { uppercasePage0, titlecasePage1, uppercasePage2, uppercasePage3, uppercasePage4, uppercasePage5, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, titlecasePage16, emptyPage, emptyPage, uppercasePage19, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, |
︙ | ︙ | |||
12740 12741 12742 12743 12744 12745 12746 | emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, uppercasePage489 }; | | | | | | | | 12738 12739 12740 12741 12742 12743 12744 12745 12746 12747 12748 12749 12750 12751 12752 12753 12754 12755 12756 12757 12758 12759 12760 12761 12762 12763 | emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, uppercasePage489 }; const OFUnichar *const OFUnicodeCaseFoldingTable[0x1EA] = { caseFoldingPage0, caseFoldingPage1, lowercasePage2, caseFoldingPage3, lowercasePage4, lowercasePage5, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, lowercasePage16, emptyPage, emptyPage, caseFoldingPage19, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, caseFoldingPage28, emptyPage, caseFoldingPage30, caseFoldingPage31, emptyPage, lowercasePage33, emptyPage, emptyPage, lowercasePage36, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, lowercasePage44, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, |
︙ | ︙ | |||
12798 12799 12800 12801 12802 12803 12804 | emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, lowercasePage166, lowercasePage167, emptyPage, emptyPage, emptyPage, | | | 12796 12797 12798 12799 12800 12801 12802 12803 12804 12805 12806 12807 12808 12809 12810 | emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, lowercasePage166, lowercasePage167, emptyPage, emptyPage, emptyPage, caseFoldingPage171, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, |
︙ | ︙ | |||
12907 12908 12909 12910 12911 12912 12913 | emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, lowercasePage489 }; | | | 12905 12906 12907 12908 12909 12910 12911 12912 12913 12914 12915 12916 12917 12918 12919 | emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, emptyPage, lowercasePage489 }; const char *const *OFUnicodeDecompositionTable[0x2FB] = { decompositionPage0, decompositionPage1, decompositionPage2, decompositionPage3, decompositionPage4, emptyDecompositionPage, decompositionPage6, emptyDecompositionPage, emptyDecompositionPage, decompositionPage9, decompositionPage10, decompositionPage11, decompositionPage12, decompositionPage13, emptyDecompositionPage, decompositionPage15, decompositionPage16, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, |
︙ | ︙ | |||
13165 13166 13167 13168 13169 13170 13171 | emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, decompositionPage760, decompositionPage761, decompositionPage762 }; | | | 13163 13164 13165 13166 13167 13168 13169 13170 13171 13172 13173 13174 13175 13176 13177 | emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, decompositionPage760, decompositionPage761, decompositionPage762 }; const char *const *OFUnicodeDecompositionCompatTable[0x2FB] = { decompCompatPage0, decompCompatPage1, decompCompatPage2, decompCompatPage3, decompositionPage4, decompCompatPage5, decompCompatPage6, emptyDecompositionPage, emptyDecompositionPage, decompositionPage9, decompositionPage10, decompositionPage11, decompCompatPage12, decompCompatPage13, decompCompatPage14, decompCompatPage15, decompCompatPage16, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, emptyDecompositionPage, |
︙ | ︙ |
Modified src/unistd_wrapper.h from [b988d01088] to [10576ea4f7].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified tests/ForwardingTests.m from [193bc733e3] to [de62832427].
1 | /* | < < | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" #define FORMAT @"%@ %@ %@ %@ %@ %@ %@ %@ %@ %g %g %g %g %g %g %g %g %g" #define ARGS @"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h", @"i", \ 1.5, 2.25, 3.125, 4.0625, 5.03125, 6.5, 7.25, 8.0, 9.0 #define RESULT @"a b c d e f g h i 1.5 2.25 3.125 4.0625 5.03125 6.5 7.25 8 9" static OFString *const module = @"Forwarding"; static size_t forwardingsCount = 0; static bool success = false; static id target = nil; struct StretTest { char buffer[1024]; }; @interface ForwardingTest: OFObject @end @interface ForwardingTest (Test) + (void)test; - (void)test; - (uint32_t)forwardingTargetTest: (intptr_t)a0 : (intptr_t)a1 : (double)a2 : (double)a3; - (OFString *)forwardingTargetVarArgTest: (OFConstantString *)format, ...; - (long double)forwardingTargetFPRetTest; - (struct StretTest)forwardingTargetStRetTest; - (void)forwardingTargetNilTest; - (void)forwardingTargetSelfTest; - (struct StretTest)forwardingTargetNilStRetTest; - (struct StretTest)forwardingTargetSelfStRetTest; @end @interface ForwardingTarget: OFObject @end static void test(id self, SEL _cmd) { success = true; } @implementation ForwardingTest + (bool)resolveClassMethod: (SEL)selector { forwardingsCount++; if (sel_isEqual(selector, @selector(test))) { class_replaceMethod(object_getClass(self), @selector(test), (IMP)test, "v#:"); return YES; } return NO; } + (bool)resolveInstanceMethod: (SEL)selector { forwardingsCount++; if (sel_isEqual(selector, @selector(test))) { class_replaceMethod(self, @selector(test), (IMP)test, "v@:"); return YES; } return NO; |
︙ | ︙ | |||
125 126 127 128 129 130 131 | @implementation ForwardingTarget - (uint32_t)forwardingTargetTest: (intptr_t)a0 : (intptr_t)a1 : (double)a2 : (double)a3 { | | | | | | | | | | | | > | | | > | | | | | > | | | | | | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | @implementation ForwardingTarget - (uint32_t)forwardingTargetTest: (intptr_t)a0 : (intptr_t)a1 : (double)a2 : (double)a3 { OFEnsure(self == target); if (a0 != (intptr_t)0xDEADBEEF) return 0; if (a1 != -1) return 0; if (a2 != 1.25) return 0; if (a3 != 2.75) return 0; return 0x12345678; } - (OFString *)forwardingTargetVarArgTest: (OFConstantString *)format, ... { va_list args; OFString *ret; OFEnsure(self == target); va_start(args, format); ret = [[[OFString alloc] initWithFormat: format arguments: args] autorelease]; va_end(args); return ret; } - (long double)forwardingTargetFPRetTest { OFEnsure(self == target); return 12345678.00006103515625; } - (struct StretTest)forwardingTargetStRetTest { struct StretTest ret = { { 0 } }; OFEnsure(self == target); memcpy(ret.buffer, "abcdefghijklmnopqrstuvwxyz", 27); return ret; } @end @implementation TestsAppDelegate (ForwardingTests) - (void)forwardingTests { void *pool = objc_autoreleasePoolPush(); TEST(@"Forwarding a message and adding a class method", R([ForwardingTest test]) && success && R([ForwardingTest test]) && forwardingsCount == 1); ForwardingTest *testObject = [[[ForwardingTest alloc] init] autorelease]; success = false; forwardingsCount = 0; TEST(@"Forwarding a message and adding an instance method", R([testObject test]) && success && R([testObject test]) && forwardingsCount == 1); #ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR target = [[[ForwardingTarget alloc] init] autorelease]; TEST(@"-[forwardingTargetForSelector:]", [testObject forwardingTargetTest: 0xDEADBEEF : -1 : 1.25 : 2.75] == 0x12345678) TEST(@"-[forwardingTargetForSelector:] variable arguments", [[testObject forwardingTargetVarArgTest: FORMAT, ARGS] isEqual: RESULT]) /* * Don't try fpret on Win64 if we don't have stret forwarding, as * long double is handled as a struct there. */ # if !defined(OF_WINDOWS) || !defined(OF_X86_64) || \ defined(OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET) TEST(@"-[forwardingTargetForSelector:] fp return", [testObject forwardingTargetFPRetTest] == 12345678.00006103515625) # endif # ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET TEST(@"-[forwardingTargetForSelector:] struct return", !memcmp([testObject forwardingTargetStRetTest].buffer, "abcdefghijklmnopqrstuvwxyz", 27)) # endif EXPECT_EXCEPTION(@"-[forwardingTargetForSelector:] nil target", OFNotImplementedException, [testObject forwardingTargetNilTest]) EXPECT_EXCEPTION(@"-[forwardingTargetForSelector:] self target", OFNotImplementedException, [testObject forwardingTargetSelfTest]) # ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET EXPECT_EXCEPTION(@"-[forwardingTargetForSelector:] nil target + " @"stret", OFNotImplementedException, [testObject forwardingTargetNilStRetTest]) EXPECT_EXCEPTION(@"-[forwardingTargetForSelector:] self target + " @"stret", OFNotImplementedException, [testObject forwardingTargetSelfStRetTest]) # endif #endif objc_autoreleasePoolPop(pool); } @end |
Modified tests/ImportTest.m from [8e80f2e0e7] to [50763ee365].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified tests/Makefile from [6a6c363390] to [bb692e21b0].
1 2 | include ../extra.mk | | > > < < > > > < < < < < < | | | | > > > > > < < | > | | | > | | > | > | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | include ../extra.mk SUBDIRS = ${TESTPLUGIN} \ ${OBJC_SYNC} \ terminal CLEAN = EBOOT.PBP \ boot.dol \ ${PROG_NOINST}.arm9 \ ${PROG_NOINST}.nds DISTCLEAN = Info.plist PROG_NOINST = tests${PROG_SUFFIX} STATIC_LIB_NOINST = ${TESTS_STATIC_LIB} SRCS = ForwardingTests.m \ OFArrayTests.m \ ${OF_BLOCK_TESTS_M} \ OFCharacterSetTests.m \ OFDataTests.m \ OFDateTests.m \ OFDictionaryTests.m \ OFInvocationTests.m \ OFJSONTests.m \ OFListTests.m \ OFLocaleTests.m \ OFMethodSignatureTests.m \ OFNotificationCenterTests.m \ OFNumberTests.m \ OFObjectTests.m \ OFPBKDF2Tests.m \ OFPropertyListTests.m \ OFScryptTests.m \ OFSetTests.m \ OFStreamTests.m \ OFStringTests.m \ OFSystemInfoTests.m \ OFURLTests.m \ OFValueTests.m \ OFXMLElementBuilderTests.m \ OFXMLNodeTests.m \ OFXMLParserTests.m \ RuntimeTests.m \ ${RUNTIME_ARC_TESTS_M} \ TestsAppDelegate.m \ ${USE_SRCS_FILES} \ ${USE_SRCS_PLUGINS} \ ${USE_SRCS_SOCKETS} \ ${USE_SRCS_THREADS} \ ${USE_SRCS_WINDOWS} SRCS_FILES = OFHMACTests.m \ OFINIFileTests.m \ OFMD5HashTests.m \ OFRIPEMD160HashTests.m \ OFSerializationTests.m \ OFSHA1HashTests.m \ OFSHA224HashTests.m \ OFSHA256HashTests.m \ OFSHA384HashTests.m \ OFSHA512HashTests.m SRCS_PLUGINS = OFPluginTests.m SRCS_SOCKETS = OFDNSResolverTests.m \ ${OF_HTTP_CLIENT_TESTS_M} \ OFHTTPCookieTests.m \ OFHTTPCookieManagerTests.m \ OFKernelEventObserverTests.m \ OFSocketTests.m \ OFTCPSocketTests.m \ OFUDPSocketTests.m \ ${USE_SRCS_IPX} \ ${USE_SRCS_UNIX_SOCKETS} SRCS_IPX = OFIPXSocketTests.m \ OFSPXSocketTests.m \ OFSPXStreamSocketTests.m SRCS_UNIX_SOCKETS = OFUNIXDatagramSocketTests.m \ OFUNIXStreamSocketTests.m SRCS_THREADS = OFThreadTests.m SRCS_WINDOWS = OFWindowsRegistryKeyTests.m IOS_USER ?= mobile IOS_TMP ?= /tmp/objfw-test include ../buildsys.mk .PHONY: run run-on-ios run-on-android run: rm -f libobjfw.so.${OBJFW_LIB_MAJOR} rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} rm -f objfw${OBJFW_LIB_MAJOR}.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR} rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib rm -f ${OBJFWRT_AMIGA_LIB} if test -f ../src/libobjfw.so; then \ ${LN_S} ../src/libobjfw.so libobjfw.so.${OBJFW_LIB_MAJOR}; \ ${LN_S} ../src/libobjfw.so \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ elif test -f ../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; then \ ${LN_S} ../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ fi if test -f ../src/objfw${OBJFW_LIB_MAJOR}.dll; then \ ${LN_S} ../src/objfw${OBJFW_LIB_MAJOR}.dll \ objfw${OBJFW_LIB_MAJOR}.dll; \ fi if test -f ../src/libobjfw.dylib; then \ ${LN_S} ../src/libobjfw.dylib \ libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ fi if test -f ../src/runtime/libobjfwrt.so; then \ ${LN_S} ../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ ${LN_S} ../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ elif test -f ../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; then \ ${LN_S} ../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ fi if test -f ../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll; then \ ${LN_S} ../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll \ objfwrt${OBJFWRT_LIB_MAJOR}.dll; \ fi if test -f ../src/runtime/libobjfwrt.dylib; then \ ${LN_S} ../src/runtime/libobjfwrt.dylib \ libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ fi if test -f ../src/runtime/${OBJFWRT_AMIGA_LIB}; then \ ${LN_S} ../src/runtime/${OBJFWRT_AMIGA_LIB} \ ${OBJFWRT_AMIGA_LIB}; \ fi LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ DYLD_FRAMEWORK_PATH=../src:../src/runtime$${DYLD_FRAMEWORK_PATH+:}$$DYLD_FRAMEWORK_PATH \ DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ LIBRARY_PATH=.$${LIBRARY_PATH+:}$$LIBRARY_PATH \ ASAN_OPTIONS=allocator_may_return_null=1 \ ${WRAPPER} ./${PROG_NOINST}; EXIT=$$?; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR}; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ rm -f objfw${OBJFW_LIB_MAJOR}.dll; \ rm -f libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll; \ rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ exit $$EXIT run-on-ios: all if [ -z "${IOS_HOST}" ]; then \ echo "Please set IOS_HOST to the hostname of your iOS host!"; \ exit 1; \ |
︙ | ︙ |
Deleted tests/OFASN1DERParsingTests.m version [dd4c3da7d2].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted tests/OFASN1DERRepresentationTests.m version [6efb5a6e9d].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified tests/OFArrayTests.m from [650205073d] to [b0ef1c947a].
1 | /* | < < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *module; static OFString *const cArray[] = { @"Foo", @"Bar", @"Baz" }; @interface SimpleArray: OFArray { |
︙ | ︙ | |||
49 50 51 52 53 54 55 | [self release]; @throw e; } return self; } | | < | < | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | [self release]; @throw e; } return self; } - (instancetype)initWithObject: (id)object arguments: (va_list)arguments { self = [super init]; @try { _array = [[OFMutableArray alloc] initWithObject: object arguments: arguments]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithObjects: (id const *)objects count: (size_t)count { self = [super init]; @try { _array = [[OFMutableArray alloc] initWithObjects: objects count: count]; } @catch (id e) { |
︙ | ︙ | |||
106 107 108 109 110 111 112 | @implementation SimpleMutableArray + (void)initialize { if (self == [SimpleMutableArray class]) [self inheritMethodsFromClass: [SimpleArray class]]; } | | < | < | < | < | | | | > | | < | | | > | | | | > | > | | | | | | | | | | | | | | | | | | | < | | | | | | | | | < | | | | > > > | > | | > > | | | > | | | | < < > > > | | | > | | | | | | | | | | | | | | | > | | | | > | | | < | | | | | | < | | < | < | < | | | | | | | | | | | > | | | | | | | | | | | | | > | | | | | | | | | > | | | | | | | | > | | | | | | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 | @implementation SimpleMutableArray + (void)initialize { if (self == [SimpleMutableArray class]) [self inheritMethodsFromClass: [SimpleArray class]]; } - (void)insertObject: (id)object atIndex: (size_t)idx { [_array insertObject: object atIndex: idx]; } - (void)replaceObjectAtIndex: (size_t)idx withObject: (id)object { [_array replaceObjectAtIndex: idx withObject: object]; } - (void)removeObjectAtIndex: (size_t)idx { [_array removeObjectAtIndex: idx]; } @end @implementation TestsAppDelegate (OFArrayTests) - (void)arrayTestsWithClass: (Class)arrayClass mutableClass: (Class)mutableArrayClass { void *pool = objc_autoreleasePoolPush(); OFArray *array1, *array2; OFMutableArray *mutableArray1, *mutableArray2; OFEnumerator *enumerator; id object; bool ok; size_t i; TEST(@"+[array]", (mutableArray1 = [mutableArrayClass array])) TEST(@"+[arrayWithObjects:]", (array1 = [arrayClass arrayWithObjects: @"Foo", @"Bar", @"Baz", nil])) TEST(@"+[arrayWithObjects:count:]", (array2 = [arrayClass arrayWithObjects: cArray count: 3]) && [array2 isEqual: array1]) TEST(@"-[description]", [array1.description isEqual: @"(\n\tFoo,\n\tBar,\n\tBaz\n)"]) TEST(@"-[addObject:]", R([mutableArray1 addObject: cArray[0]]) && R([mutableArray1 addObject: cArray[2]])) TEST(@"-[insertObject:atIndex:]", R([mutableArray1 insertObject: cArray[1] atIndex: 1])) TEST(@"-[count]", mutableArray1.count == 3 && array1.count == 3 && array2.count == 3) TEST(@"-[isEqual:]", [mutableArray1 isEqual: array1] && [array1 isEqual: array2]) TEST(@"-[objectAtIndex:]", [[mutableArray1 objectAtIndex: 0] isEqual: cArray[0]] && [[mutableArray1 objectAtIndex: 1] isEqual: cArray[1]] && [[mutableArray1 objectAtIndex: 2] isEqual: cArray[2]] && [[array1 objectAtIndex: 0] isEqual: cArray[0]] && [[array1 objectAtIndex: 1] isEqual: cArray[1]] && [[array1 objectAtIndex: 2] isEqual: cArray[2]] && [[array2 objectAtIndex: 0] isEqual: cArray[0]] && [[array2 objectAtIndex: 1] isEqual: cArray[1]] && [[array2 objectAtIndex: 2] isEqual: cArray[2]]) TEST(@"-[containsObject:]", [array1 containsObject: cArray[1]] && ![array1 containsObject: @"nonexistent"]) TEST(@"-[containsObjectIdenticalTo:]", [array1 containsObjectIdenticalTo: cArray[1]] && ![array1 containsObjectIdenticalTo: [OFString stringWithString: cArray[1]]]) TEST(@"-[indexOfObject:]", [array1 indexOfObject: cArray[1]] == 1) TEST(@"-[indexOfObjectIdenticalTo:]", [array2 indexOfObjectIdenticalTo: cArray[1]] == 1) TEST(@"-[objectsInRange:]", [[array1 objectsInRange: OFRangeMake(1, 2)] isEqual: [arrayClass arrayWithObjects: cArray[1], cArray[2], nil]]) TEST(@"-[replaceObject:withObject:]", R([mutableArray1 replaceObject: cArray[1] withObject: cArray[0]]) && [[mutableArray1 objectAtIndex: 0] isEqual: cArray[0]] && [[mutableArray1 objectAtIndex: 1] isEqual: cArray[0]] && [[mutableArray1 objectAtIndex: 2] isEqual: cArray[2]]) TEST(@"-[replaceObject:identicalTo:]", R([mutableArray1 replaceObjectIdenticalTo: cArray[0] withObject: cArray[1]]) && [[mutableArray1 objectAtIndex: 0] isEqual: cArray[1]] && [[mutableArray1 objectAtIndex: 1] isEqual: cArray[0]] && [[mutableArray1 objectAtIndex: 2] isEqual: cArray[2]]) TEST(@"-[replaceObjectAtIndex:withObject:]", R([mutableArray1 replaceObjectAtIndex: 0 withObject: cArray[0]]) && [[mutableArray1 objectAtIndex: 0] isEqual: cArray[0]] && [[mutableArray1 objectAtIndex: 1] isEqual: cArray[0]] && [[mutableArray1 objectAtIndex: 2] isEqual: cArray[2]]) TEST(@"-[removeObject:]", R([mutableArray1 removeObject: cArray[0]]) && mutableArray1.count == 1) [mutableArray1 addObject: cArray[0]]; TEST(@"-[removeObjectIdenticalTo:]", R([mutableArray1 removeObjectIdenticalTo: cArray[2]]) && mutableArray1.count == 1) mutableArray2 = [[array1 mutableCopy] autorelease]; TEST(@"-[removeObjectAtIndex:]", R([mutableArray2 removeObjectAtIndex: 1]) && mutableArray2.count == 2 && [[mutableArray2 objectAtIndex: 1] isEqual: cArray[2]]) mutableArray2 = [[array1 mutableCopy] autorelease]; TEST(@"-[removeObjectsInRange:]", R([mutableArray2 removeObjectsInRange: OFRangeMake(0, 2)]) && mutableArray2.count == 1 && [[mutableArray2 objectAtIndex: 0] isEqual: cArray[2]]) mutableArray2 = [[array1 mutableCopy] autorelease]; [mutableArray2 addObject: @"qux"]; [mutableArray2 addObject: @"last"]; TEST(@"-[reverse]", R([mutableArray2 reverse]) && [mutableArray2 isEqual: [arrayClass arrayWithObjects: @"last", @"qux", @"Baz", @"Bar", @"Foo", nil]]) mutableArray2 = [[array1 mutableCopy] autorelease]; [mutableArray2 addObject: @"qux"]; [mutableArray2 addObject: @"last"]; TEST(@"-[reversedArray]", [[mutableArray2 reversedArray] isEqual: [arrayClass arrayWithObjects: @"last", @"qux", @"Baz", @"Bar", @"Foo", nil]]) mutableArray2 = [[array1 mutableCopy] autorelease]; [mutableArray2 addObject: @"0"]; [mutableArray2 addObject: @"z"]; TEST(@"-[sortedArray]", [[mutableArray2 sortedArray] isEqual: [arrayClass arrayWithObjects: @"0", @"Bar", @"Baz", @"Foo", @"z", nil]] && [[mutableArray2 sortedArrayUsingSelector: @selector(compare:) options: OFArraySortDescending] isEqual: [arrayClass arrayWithObjects: @"z", @"Foo", @"Baz", @"Bar", @"0", nil]]) EXPECT_EXCEPTION(@"Detect out of range in -[objectAtIndex:]", OFOutOfRangeException, [array1 objectAtIndex: array1.count]) EXPECT_EXCEPTION(@"Detect out of range in -[removeObjectsInRange:]", OFOutOfRangeException, [mutableArray1 removeObjectsInRange: OFRangeMake(0, mutableArray1.count + 1)]) TEST(@"-[componentsJoinedByString:]", (array2 = [arrayClass arrayWithObjects: @"", @"a", @"b", @"c", nil]) && [[array2 componentsJoinedByString: @" "] isEqual: @" a b c"] && (array2 = [arrayClass arrayWithObject: @"foo"]) && [[array2 componentsJoinedByString: @" "] isEqual: @"foo"]) TEST(@"-[componentsJoinedByString:options]", (array2 = [arrayClass arrayWithObjects: @"", @"foo", @"", @"", @"bar", @"", nil]) && [[array2 componentsJoinedByString: @" " options: OFArraySkipEmptyComponents] isEqual: @"foo bar"]) mutableArray1 = [[array1 mutableCopy] autorelease]; ok = true; i = 0; TEST(@"-[objectEnumerator]", (enumerator = [mutableArray1 objectEnumerator])) while ((object = [enumerator nextObject]) != nil) { if (![object isEqual: cArray[i]]) ok = false; [mutableArray1 replaceObjectAtIndex: i withObject: @""]; i++; } if (mutableArray1.count != i) ok = false; TEST(@"OFEnumerator's -[nextObject]", ok) [mutableArray1 removeObjectAtIndex: 0]; EXPECT_EXCEPTION(@"Detection of mutation during enumeration", OFEnumerationMutationException, [enumerator nextObject]) mutableArray1 = [[array1 mutableCopy] autorelease]; ok = true; i = 0; for (OFString *string in mutableArray1) { if (![string isEqual: cArray[i]]) ok = false; [mutableArray1 replaceObjectAtIndex: i withObject: @""]; i++; } if (mutableArray1.count != i) ok = false; TEST(@"Fast Enumeration", ok) [mutableArray1 replaceObjectAtIndex: 0 withObject: cArray[0]]; [mutableArray1 replaceObjectAtIndex: 1 withObject: cArray[1]]; [mutableArray1 replaceObjectAtIndex: 2 withObject: cArray[2]]; ok = false; i = 0; @try { for (OFString *string in mutableArray1) { (void)string; if (i == 0) [mutableArray1 addObject: @""]; i++; } } @catch (OFEnumerationMutationException *e) { ok = true; } TEST(@"Detection of mutation during Fast Enumeration", ok) [mutableArray1 removeLastObject]; #ifdef OF_HAVE_BLOCKS { __block bool blockOK = true; __block size_t count = 0; OFArray *compareArray = array1; OFMutableArray *mutableArray3; mutableArray1 = [[array1 mutableCopy] autorelease]; [mutableArray1 enumerateObjectsUsingBlock: ^ (id object_, size_t idx, bool *stop) { count++; if (![object_ isEqual: [compareArray objectAtIndex: idx]]) blockOK = false; }]; if (count != compareArray.count) blockOK = false; TEST(@"Enumeration using blocks", blockOK) blockOK = false; mutableArray3 = mutableArray1; @try { [mutableArray3 enumerateObjectsUsingBlock: ^ (id object_, size_t idx, bool *stop) { [mutableArray3 removeObjectAtIndex: idx]; }]; } @catch (OFEnumerationMutationException *e) { blockOK = true; } @catch (OFOutOfRangeException *e) { /* * Out of bounds access due to enumeration not being * detected. */ } TEST(@"Detection of mutation during enumeration using blocks", blockOK) } TEST(@"-[replaceObjectsUsingBlock:]", R([mutableArray1 replaceObjectsUsingBlock: ^ id (id object_, size_t idx) { switch (idx) { case 0: return @"foo"; case 1: return @"bar"; } return nil; }]) && [mutableArray1.description isEqual: @"(\n\tfoo,\n\tbar\n)"]) TEST(@"-[mappedArrayUsingBlock:]", [[mutableArray1 mappedArrayUsingBlock: ^ id (id object_, size_t idx) { switch (idx) { case 0: return @"foobar"; case 1: return @"qux"; } return nil; }].description isEqual: @"(\n\tfoobar,\n\tqux\n)"]) TEST(@"-[filteredArrayUsingBlock:]", [[mutableArray1 filteredArrayUsingBlock: ^ bool (id object_, size_t idx) { return [object_ isEqual: @"foo"]; }].description isEqual: @"(\n\tfoo\n)"]) TEST(@"-[foldUsingBlock:]", [[arrayClass arrayWithObjects: [OFMutableString string], @"foo", @"bar", @"baz", nil] foldUsingBlock: ^ id (id left, id right) { [left appendString: right]; return left; }]) #endif TEST(@"-[valueForKey:]", [[[arrayClass arrayWithObjects: @"foo", @"bar", @"quxqux", nil] valueForKey: @"length"] isEqual: [arrayClass arrayWithObjects: [OFNumber numberWithInt: 3], [OFNumber numberWithInt: 3], [OFNumber numberWithInt: 6], nil]] && [[[arrayClass arrayWithObjects: @"1", @"2", nil] valueForKey: @"@count"] isEqual: [OFNumber numberWithInt: 2]]) mutableArray1 = [mutableArrayClass arrayWithObjects: [OFMutableURL URLWithString: @"http://foo.bar/"], [OFMutableURL URLWithString: @"http://bar.qux/"], [OFMutableURL URLWithString: @"http://qux.quxqux/"], nil]; TEST(@"-[setValue:forKey:]", R([mutableArray1 setValue: [OFNumber numberWithShort: 1234] forKey: @"port"]) && [mutableArray1 isEqual: [arrayClass arrayWithObjects: [OFURL URLWithString: @"http://foo.bar:1234/"], [OFURL URLWithString: @"http://bar.qux:1234/"], [OFURL URLWithString: @"http://qux.quxqux:1234/"], nil]]) objc_autoreleasePoolPop(pool); } |
︙ | ︙ |
Modified tests/OFBlockTests.m from [0c40afc8f7] to [d2cc5b8a58].
1 | /* | < < | | | | | | | > | > | > | | | | | | > | > > | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFBlock"; #if defined(OF_OBJFW_RUNTIME) extern struct objc_class _NSConcreteStackBlock; extern struct objc_class _NSConcreteGlobalBlock; extern struct objc_class _NSConcreteMallocBlock; #elif defined(OF_APPLE_RUNTIME) extern void *_NSConcreteStackBlock; extern void *_NSConcreteGlobalBlock; extern void *_NSConcreteMallocBlock; #endif static void (^globalBlock)(void) = ^ {}; static int (^returnStackBlock(void))(void) { __block int i = 42; return [Block_copy(^ int { return ++i; }) autorelease]; } static double forwardTest(void) { __block double d; void (^block)(void) = Block_copy(^ { d = 5; }); block(); Block_release(block); return d; } @implementation TestsAppDelegate (OFBlockTests) - (void)blockTests { void *pool = objc_autoreleasePoolPush(); __block int x; void (^stackBlock)(void) = ^ { x = 0; (void)x; }; void (^mallocBlock)(void); int (^voidBlock)(void); TEST(@"Class of stack block", (Class)&_NSConcreteStackBlock == objc_getClass("OFStackBlock") && [stackBlock isKindOfClass: [OFBlock class]]) #if !defined(OF_WINDOWS) || !defined(__clang__) || !defined(OF_NO_SHARED) /* * Causes a linker error on Windows with Clang when compiling as a * static library. This is a bug in Clang. */ TEST(@"Class of global block", (Class)&_NSConcreteGlobalBlock == objc_getClass("OFGlobalBlock") && [globalBlock isKindOfClass: [OFBlock class]]) #endif TEST(@"Class of a malloc block", (Class)&_NSConcreteMallocBlock == objc_getClass("OFMallocBlock")) TEST(@"Copying a stack block", (mallocBlock = [[stackBlock copy] autorelease]) && [mallocBlock class] == objc_getClass("OFMallocBlock") && [mallocBlock isKindOfClass: [OFBlock class]]) TEST(@"Copying a stack block and referencing its variable", forwardTest() == 5) TEST(@"Copying a stack block and using its copied variable", (voidBlock = returnStackBlock()) && voidBlock() == 43 && voidBlock() == 44 && voidBlock() == 45) TEST(@"Copying a global block", (id)globalBlock == [[globalBlock copy] autorelease]) #ifndef __clang_analyzer__ TEST(@"Copying a malloc block", (id)mallocBlock == [mallocBlock copy] && [mallocBlock retainCount] == 2) #endif TEST(@"Autorelease a stack block", R([stackBlock autorelease])) TEST(@"Autorelease a global block", R([globalBlock autorelease])) #ifndef __clang_analyzer__ TEST(@"Autorelease a malloc block", R([mallocBlock autorelease])) #endif objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFCharacterSetTests.m from [b475a2bd21] to [9f65e98d38].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | #import "TestsAppDelegate.h" #import "OFCharacterSet.h" #import "OFBitSetCharacterSet.h" #import "OFRangeCharacterSet.h" | | | | | | | | | | | | | > | | | | | | | | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | #import "TestsAppDelegate.h" #import "OFCharacterSet.h" #import "OFBitSetCharacterSet.h" #import "OFRangeCharacterSet.h" static OFString *module; @interface SimpleCharacterSet: OFCharacterSet @end @implementation SimpleCharacterSet - (bool)characterIsMember: (OFUnichar)character { return (character % 2 == 0); } @end @implementation TestsAppDelegate (OFCharacterSetTests) - (void)characterSetTests { void *pool = objc_autoreleasePoolPush(); OFCharacterSet *characterSet, *invertedCharacterSet; bool ok; module = @"OFCharacterSet"; characterSet = [[[SimpleCharacterSet alloc] init] autorelease]; ok = true; for (OFUnichar c = 0; c < 65536; c++) { if (c % 2 == 0) { if (![characterSet characterIsMember: c]) ok = false; } else if ([characterSet characterIsMember: c]) ok = false; } TEST(@"-[characterIsMember:]", ok); module = @"OFBitSetCharacterSet"; TEST(@"+[characterSetWithCharactersInString:]", (characterSet = [OFCharacterSet characterSetWithCharactersInString: @"0123456789"]) && [characterSet isKindOfClass: [OFBitSetCharacterSet class]]) ok = true; for (OFUnichar c = 0; c < 65536; c++) { if (c >= '0' && c <= '9') { if (![characterSet characterIsMember: c]) ok = false; } else if ([characterSet characterIsMember: c]) ok = false; } TEST(@"-[characterIsMember:]", ok); module = @"OFRangeCharacterSet"; TEST(@"+[characterSetWithRange:]", (characterSet = [OFCharacterSet characterSetWithRange: OFRangeMake('0', 10)]) && [characterSet isKindOfClass: [OFRangeCharacterSet class]]) ok = true; for (OFUnichar c = 0; c < 65536; c++) { if (c >= '0' && c <= '9') { if (![characterSet characterIsMember: c]) ok = false; } else if ([characterSet characterIsMember: c]) ok = false; } TEST(@"-[characterIsMember:]", ok); ok = true; invertedCharacterSet = characterSet.invertedSet; for (OFUnichar c = 0; c < 65536; c++) { if (c >= '0' && c <= '9') { if ([invertedCharacterSet characterIsMember: c]) ok = false; } else if (![invertedCharacterSet characterIsMember: c]) ok = false; } TEST(@"-[invertedSet]", ok); TEST(@"Inverting -[invertedSet] returns original set", invertedCharacterSet.invertedSet == characterSet) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFDNSResolverTests.m from [e970066231] to [b7997ffc05].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | @implementation TestsAppDelegate (OFDNSResolverTests) - (void)DNSResolverTests { void *pool = objc_autoreleasePoolPush(); OFDNSResolver *resolver = [OFDNSResolver resolver]; OFMutableString *staticHosts = [OFMutableString string]; | | | | | | | | | | | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | @implementation TestsAppDelegate (OFDNSResolverTests) - (void)DNSResolverTests { void *pool = objc_autoreleasePoolPush(); OFDNSResolver *resolver = [OFDNSResolver resolver]; OFMutableString *staticHosts = [OFMutableString string]; [OFStdOut setForegroundColor: [OFColor lime]]; for (OFString *host in resolver.staticHosts) { OFString *IPs; if (staticHosts.length > 0) [staticHosts appendString: @"; "]; IPs = [[resolver.staticHosts objectForKey: host] componentsJoinedByString: @", "]; [staticHosts appendFormat: @"%@=(%@)", host, IPs]; } [OFStdOut writeFormat: @"[OFDNSResolver] Static hosts: %@\n", staticHosts]; [OFStdOut writeFormat: @"[OFDNSResolver] Name servers: %@\n", [resolver.nameServers componentsJoinedByString: @", "]]; [OFStdOut writeFormat: @"[OFDNSResolver] Local domain: %@\n", resolver.localDomain]; [OFStdOut writeFormat: @"[OFDNSResolver] Search domains: %@\n", [resolver.searchDomains componentsJoinedByString: @", "]]; [OFStdOut writeFormat: @"[OFDNSResolver] Timeout: %lf\n", resolver.timeout]; [OFStdOut writeFormat: @"[OFDNSResolver] Max attempts: %u\n", resolver.maxAttempts]; [OFStdOut writeFormat: @"[OFDNSResolver] Min number of dots in absolute name: %u\n", resolver.minNumberOfDotsInAbsoluteName]; [OFStdOut writeFormat: @"[OFDNSResolver] Uses TCP: %u\n", resolver.usesTCP]; [OFStdOut writeFormat: @"[OFDNSResolver] Config reload interval: %lf\n", resolver.configReloadInterval]; objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFDataTests.m from [ec82a4e0aa] to [cc1d29fd59].
1 | /* | < < | | < | | | | < | | | | | | | | | < | > | | | | | | | | | < | < | | < | > | | | | < | | | | > | < < | < | | > | > | > | > > > > > > | > | | > | > | < | < < < < | < | | > | > > | < | > | | | > | < | > | | > | | < | > | | | < < | | | | < < | | < | > | > > > | | | > | > > | | > > | | > > | | > > | | > > > | | | | < | | | | | | > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFData"; @implementation TestsAppDelegate (OFDataTests) - (void)dataTests { void *pool = objc_autoreleasePoolPush(); OFMutableData *mutableData; OFData *data; void *raw[2]; OFRange range; TEST(@"+[dataWithItemSize:]", (mutableData = [OFMutableData dataWithItemSize: 4096])) raw[0] = OFAllocMemory(1, 4096); raw[1] = OFAllocMemory(1, 4096); memset(raw[0], 0xFF, 4096); memset(raw[1], 0x42, 4096); TEST(@"-[addItem:]", R([mutableData addItem: raw[0]]) && R([mutableData addItem: raw[1]])) TEST(@"-[itemAtIndex:]", memcmp([mutableData itemAtIndex: 0], raw[0], 4096) == 0 && memcmp([mutableData itemAtIndex: 1], raw[1], 4096) == 0) TEST(@"-[lastItem]", memcmp(mutableData.lastItem, raw[1], 4096) == 0) TEST(@"-[count]", mutableData.count == 2) TEST(@"-[isEqual:]", (data = [OFData dataWithItems: mutableData.items count: mutableData.count itemSize: mutableData.itemSize]) && [data isEqual: mutableData] && R([mutableData removeLastItem]) && ![mutableData isEqual: data]) TEST(@"-[mutableCopy]", (mutableData = [[data mutableCopy] autorelease]) && [mutableData isEqual: data]) TEST(@"-[compare]", [mutableData compare: data] == 0 && R([mutableData removeLastItem]) && [data compare: mutableData] == OFOrderedDescending && [mutableData compare: data] == OFOrderedAscending && [[OFData dataWithItems: "aa" count: 2] compare: [OFData dataWithItems: "z" count: 1]] == OFOrderedAscending) TEST(@"-[hash]", data.hash == 0x634A529F) mutableData = [OFMutableData dataWithItems: "abcdef" count: 6]; TEST(@"-[removeLastItem]", R([mutableData removeLastItem]) && mutableData.count == 5 && memcmp(mutableData.items, "abcde", 5) == 0) TEST(@"-[removeItemsInRange:]", R([mutableData removeItemsInRange: OFRangeMake(1, 2)]) && mutableData.count == 3 && memcmp(mutableData.items, "ade", 3) == 0) TEST(@"-[insertItems:atIndex:count:]", R([mutableData insertItems: "bc" atIndex: 1 count: 2]) && mutableData.count == 5 && memcmp(mutableData.items, "abcde", 5) == 0) data = [OFData dataWithItems: "aaabaccdacaabb" count: 7 itemSize: 2]; range = [data rangeOfData: [OFData dataWithItems: "aa" count: 1 itemSize: 2] options: 0 range: OFRangeMake(0, 7)]; TEST(@"-[rangeOfData:options:range:] #1", range.location == 0 && range.length == 1) range = [data rangeOfData: [OFData dataWithItems: "aa" count: 1 itemSize: 2] options: OFDataSearchBackwards range: OFRangeMake(0, 7)]; TEST(@"-[rangeOfData:options:range:] #2", range.location == 5 && range.length == 1) range = [data rangeOfData: [OFData dataWithItems: "ac" count: 1 itemSize: 2] options: 0 range: OFRangeMake(0, 7)]; TEST(@"-[rangeOfData:options:range:] #3", range.location == 2 && range.length == 1) range = [data rangeOfData: [OFData dataWithItems: "aabb" count: 2 itemSize: 2] options: 0 range: OFRangeMake(0, 7)]; TEST(@"-[rangeOfData:options:range:] #4", range.location == 5 && range.length == 2) TEST(@"-[rangeOfData:options:range:] #5", R(range = [data rangeOfData: [OFData dataWithItems: "aa" count: 1 itemSize: 2] options: 0 range: OFRangeMake(1, 6)]) && range.location == 5 && range.length == 1) range = [data rangeOfData: [OFData dataWithItems: "aa" count: 1 itemSize: 2] options: OFDataSearchBackwards range: OFRangeMake(0, 5)]; TEST(@"-[rangeOfData:options:range:] #6", range.location == 0 && range.length == 1) EXPECT_EXCEPTION( @"-[rangeOfData:options:range:] failing on different itemSize", OFInvalidArgumentException, [data rangeOfData: [OFData dataWithItems: "aaa" count: 1 itemSize: 3] options: 0 range: OFRangeMake(0, 1)]) EXPECT_EXCEPTION( @"-[rangeOfData:options:range:] failing on out of range", OFOutOfRangeException, [data rangeOfData: [OFData dataWithItems: "" count: 0 itemSize: 2] options: 0 range: OFRangeMake(8, 1)]) TEST(@"-[subdataWithRange:]", [[data subdataWithRange: OFRangeMake(2, 4)] isEqual: [OFData dataWithItems: "accdacaa" count: 4 itemSize: 2]] && [[mutableData subdataWithRange: OFRangeMake(2, 3)] isEqual: [OFData dataWithItems: "cde" count: 3]]) EXPECT_EXCEPTION(@"-[subdataWithRange:] failing on out of range #1", OFOutOfRangeException, [data subdataWithRange: OFRangeMake(7, 1)]) EXPECT_EXCEPTION(@"-[subdataWithRange:] failing on out of range #2", OFOutOfRangeException, [mutableData subdataWithRange: OFRangeMake(6, 1)]) TEST(@"-[stringByMD5Hashing]", [mutableData.stringByMD5Hashing isEqual: @"ab56b4d92b40713acc5af89985d4b786"]) TEST(@"-[stringByRIPEMD160Hashing]", [mutableData.stringByRIPEMD160Hashing isEqual: @"973398b6e6c6cfa6b5e6a5173f195ce3274bf828"]) TEST(@"-[stringBySHA1Hashing]", [mutableData.stringBySHA1Hashing isEqual: @"03de6c570bfe24bfc328ccd7ca46b76eadaf4334"]) TEST(@"-[stringBySHA224Hashing]", [mutableData.stringBySHA224Hashing isEqual: @"bdd03d560993e675516ba5a50638b6531ac2ac3d5847c61916cfced6" ]) TEST(@"-[stringBySHA256Hashing]", [mutableData.stringBySHA256Hashing isEqual: @"36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0" @"c44ca42c"]) TEST(@"-[stringBySHA384Hashing]", [mutableData.stringBySHA384Hashing isEqual: @"4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813" @"521565abc0ec57a37ee4d8be89d097c0d2ad52f0"]) TEST(@"-[stringBySHA512Hashing]", [mutableData.stringBySHA512Hashing isEqual: @"878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3" @"cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665" @"bef2289a5c70b0a1"]) TEST(@"-[stringByBase64Encoding]", [mutableData.stringByBase64Encoding isEqual: @"YWJjZGU="]) TEST(@"+[dataWithBase64EncodedString:]", memcmp([[OFData dataWithBase64EncodedString: @"YWJjZGU="] items], "abcde", 5) == 0) TEST(@"Building strings", (mutableData = [OFMutableData dataWithItems: "Hello!" count: 6]) && R([mutableData addItem: ""]) && strcmp(mutableData.items, "Hello!") == 0) EXPECT_EXCEPTION(@"Detect out of range in -[itemAtIndex:]", OFOutOfRangeException, [mutableData itemAtIndex: mutableData.count]) EXPECT_EXCEPTION(@"Detect out of range in -[addItems:count:]", OFOutOfRangeException, [mutableData addItems: raw[0] count: SIZE_MAX]) EXPECT_EXCEPTION(@"Detect out of range in -[removeItemsInRange:]", OFOutOfRangeException, [mutableData removeItemsInRange: OFRangeMake(mutableData.count, 1)]) OFFreeMemory(raw[0]); OFFreeMemory(raw[1]); objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFDateTests.m from [3f9f2f2e15] to [f110295df2].
1 | /* | < < | > | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <time.h> #import "TestsAppDelegate.h" #import "OFStrPTime.h" static OFString *const module = @"OFDate"; @implementation TestsAppDelegate (OFDateTests) - (void)dateTests { void *pool = objc_autoreleasePoolPush(); OFDate *date1, *date2; struct tm tm; int16_t tz; const char *dstr = "Wed, 09 Jun 2021 +0200x"; TEST(@"OFStrPTime()", OFStrPTime(dstr, "%a, %d %b %Y %z", &tm, &tz) == dstr + 22 && tm.tm_wday == 3 && tm.tm_mday == 9 && tm.tm_mon == 5 && tm.tm_year == 2021 - 1900 && tz == 2 * 60) TEST(@"+[dateWithTimeIntervalSince1970:]", (date1 = [OFDate dateWithTimeIntervalSince1970: 0])) TEST(@"-[dateByAddingTimeInterval:]", (date2 = [date1 dateByAddingTimeInterval: 3600 * 25 + 5.000002])) TEST(@"-[description]", [date1.description isEqual: @"1970-01-01T00:00:00Z"] && [date2.description isEqual: @"1970-01-02T01:00:05Z"]) TEST(@"+[dateWithDateString:format:]", [[[OFDate dateWithDateString: @"2000-06-20T12:34:56+0200" format: @"%Y-%m-%dT%H:%M:%S%z"] description] isEqual: @"2000-06-20T10:34:56Z"]); EXPECT_EXCEPTION(@"Detection of unparsed in " |
︙ | ︙ | |||
75 76 77 78 79 80 81 | EXPECT_EXCEPTION(@"Detection of unparsed in " @"+[dateWithLocalDateString:format:] #2", OFInvalidFormatException, [OFDate dateWithLocalDateString: @"2000-06-20T12:34:56+0200x" format: @"%Y-%m-%dT%H:%M:%S%z"]) TEST(@"-[isEqual:]", | | | | | | > | | | | > | | | | | | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | EXPECT_EXCEPTION(@"Detection of unparsed in " @"+[dateWithLocalDateString:format:] #2", OFInvalidFormatException, [OFDate dateWithLocalDateString: @"2000-06-20T12:34:56+0200x" format: @"%Y-%m-%dT%H:%M:%S%z"]) TEST(@"-[isEqual:]", [date1 isEqual: [OFDate dateWithTimeIntervalSince1970: 0]] && ![date1 isEqual: [OFDate dateWithTimeIntervalSince1970: 0.0000001]]) TEST(@"-[compare:]", [date1 compare: date2] == OFOrderedAscending) TEST(@"-[second]", date1.second == 0 && date2.second == 5) TEST(@"-[microsecond]", date1.microsecond == 0 && date2.microsecond == 2) TEST(@"-[minute]", date1.minute == 0 && date2.minute == 0) TEST(@"-[hour]", date1.hour == 0 && date2.hour == 1) TEST(@"-[dayOfMonth]", date1.dayOfMonth == 1 && date2.dayOfMonth == 2) TEST(@"-[monthOfYear]", date1.monthOfYear == 1 && date2.monthOfYear == 1) TEST(@"-[year]", date1.year == 1970 && date2.year == 1970) TEST(@"-[dayOfWeek]", date1.dayOfWeek == 4 && date2.dayOfWeek == 5) TEST(@"-[dayOfYear]", date1.dayOfYear == 1 && date2.dayOfYear == 2) TEST(@"-[earlierDate:]", [[date1 earlierDate: date2] isEqual: date1]) TEST(@"-[laterDate:]", [[date1 laterDate: date2] isEqual: date2]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFDictionaryTests.m from [a25483183f] to [7127a0734c].
1 | /* | < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *module; static OFString *keys[] = { @"key1", @"key2" }; static OFString *values[] = { @"value1", @"value2" |
︙ | ︙ | |||
53 54 55 56 57 58 59 | [self release]; @throw e; } return self; } | | < | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | [self release]; @throw e; } return self; } - (instancetype)initWithKey: (id)key arguments: (va_list)arguments { self = [super init]; @try { _dictionary = [[OFMutableDictionary alloc] initWithKey: key arguments: arguments]; |
︙ | ︙ | |||
103 104 105 106 107 108 109 | - (id)objectForKey: (id)key { return [_dictionary objectForKey: key]; } - (size_t)count { | | | < | < | | | < | < | | | | | | < | | | | | | | | | | | | | < | | | | < | < | | | | | | < | | | | | | | | | | > | | | | | | | | | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | - (id)objectForKey: (id)key { return [_dictionary objectForKey: key]; } - (size_t)count { return _dictionary.count; } - (OFEnumerator *)keyEnumerator { return [_dictionary keyEnumerator]; } @end @implementation SimpleMutableDictionary + (void)initialize { if (self == [SimpleMutableDictionary class]) [self inheritMethodsFromClass: [SimpleDictionary class]]; } - (void)setObject: (id)object forKey: (id)key { bool existed = ([_dictionary objectForKey: key] == nil); [_dictionary setObject: object forKey: key]; if (existed) _mutations++; } - (void)removeObjectForKey: (id)key { bool existed = ([_dictionary objectForKey: key] == nil); [_dictionary removeObjectForKey: key]; if (existed) _mutations++; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { int ret = [super countByEnumeratingWithState: state objects: objects count: count]; state->mutationsPtr = &_mutations; return ret; } @end @implementation TestsAppDelegate (OFDictionaryTests) - (void)dictionaryTestsWithClass: (Class)dictionaryClass mutableClass: (Class)mutableDictionaryClass { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *mutableDict = [mutableDictionaryClass dictionary]; OFDictionary *dict; OFEnumerator *keyEnumerator, *objectEnumerator; OFArray *keysArray, *valuesArray; [mutableDict setObject: values[0] forKey: keys[0]]; [mutableDict setValue: values[1] forKey: keys[1]]; TEST(@"-[objectForKey:]", [[mutableDict objectForKey: keys[0]] isEqual: values[0]] && [[mutableDict objectForKey: keys[1]] isEqual: values[1]] && [mutableDict objectForKey: @"key3"] == nil) TEST(@"-[valueForKey:]", [[mutableDict valueForKey: keys[0]] isEqual: values[0]] && [[mutableDict valueForKey: @"@count"] isEqual: [OFNumber numberWithInt: 2]]) EXPECT_EXCEPTION(@"Catching -[setValue:forKey:] on immutable " @"dictionary", OFUndefinedKeyException, [[dictionaryClass dictionary] setValue: @"x" forKey: @"x"]) TEST(@"-[containsObject:]", [mutableDict containsObject: values[0]] && ![mutableDict containsObject: @"nonexistent"]) TEST(@"-[containsObjectIdenticalTo:]", [mutableDict containsObjectIdenticalTo: values[0]] && ![mutableDict containsObjectIdenticalTo: [OFString stringWithString: values[0]]]) TEST(@"-[description]", [[mutableDict description] isEqual: @"{\n\tkey1 = value1;\n\tkey2 = value2;\n}"]) TEST(@"-[allKeys]", [[mutableDict allKeys] isEqual: [OFArray arrayWithObjects: keys[0], keys[1], nil]]) TEST(@"-[allObjects]", [[mutableDict allObjects] isEqual: [OFArray arrayWithObjects: values[0], values[1], nil]]) TEST(@"-[keyEnumerator]", (keyEnumerator = [mutableDict keyEnumerator])) TEST(@"-[objectEnumerator]", (objectEnumerator = [mutableDict objectEnumerator])) TEST(@"OFEnumerator's -[nextObject]", [[keyEnumerator nextObject] isEqual: keys[0]] && [[objectEnumerator nextObject] isEqual: values[0]] && [[keyEnumerator nextObject] isEqual: keys[1]] && [[objectEnumerator nextObject] isEqual: values[1]] && [keyEnumerator nextObject] == nil && [objectEnumerator nextObject] == nil) [mutableDict removeObjectForKey: keys[0]]; EXPECT_EXCEPTION(@"Detection of mutation during enumeration", OFEnumerationMutationException, [keyEnumerator nextObject]); [mutableDict setObject: values[0] forKey: keys[0]]; size_t i = 0; bool ok = true; for (OFString *key in mutableDict) { if (i > 1 || ![key isEqual: keys[i]]) { ok = false; break; } [mutableDict setObject: [mutableDict objectForKey: key] forKey: key]; i++; } TEST(@"Fast Enumeration", ok) ok = false; @try { for (OFString *key in mutableDict) { (void)key; [mutableDict setObject: @"" forKey: @""]; } } @catch (OFEnumerationMutationException *e) { ok = true; } TEST(@"Detection of mutation during Fast Enumeration", ok) [mutableDict removeObjectForKey: @""]; TEST(@"-[stringByURLEncoding]", [[[OFDictionary dictionaryWithKeysAndObjects: @"foo", @"bar", @"q&x", @"q=x", nil] stringByURLEncoding] isEqual: @"q%26x=q%3Dx&foo=bar"]) #ifdef OF_HAVE_BLOCKS { __block size_t j = 0; __block bool blockOk = true; [mutableDict enumerateKeysAndObjectsUsingBlock: ^ (id key, id object, bool *stop) { if (j > 1 || ![key isEqual: keys[j]]) { blockOk = false; *stop = true; return; } [mutableDict setObject: [mutableDict objectForKey: key] forKey: key]; j++; }]; TEST(@"Enumeration using blocks", blockOk) blockOk = false; @try { [mutableDict enumerateKeysAndObjectsUsingBlock: ^ (id key, id object, bool *stop) { [mutableDict setObject: @"" forKey: @""]; }]; } @catch (OFEnumerationMutationException *e) { blockOk = true; } TEST(@"Detection of mutation during enumeration using blocks", blockOk) [mutableDict removeObjectForKey: @""]; } TEST(@"-[replaceObjectsUsingBlock:]", R([mutableDict replaceObjectsUsingBlock: ^ id (id key, id object) { if ([key isEqual: keys[0]]) return @"value_1"; if ([key isEqual: keys[1]]) return @"value_2"; return nil; }]) && [[mutableDict objectForKey: keys[0]] isEqual: @"value_1"] && [[mutableDict objectForKey: keys[1]] isEqual: @"value_2"]) TEST(@"-[mappedDictionaryUsingBlock:]", [[[mutableDict mappedDictionaryUsingBlock: ^ id (id key, id object) { if ([key isEqual: keys[0]]) return @"val1"; if ([key isEqual: keys[1]]) return @"val2"; return nil; }] description] isEqual: @"{\n\tkey1 = val1;\n\tkey2 = val2;\n}"]) TEST(@"-[filteredDictionaryUsingBlock:]", [[[mutableDict filteredDictionaryUsingBlock: ^ bool (id key, id object) { return [key isEqual: keys[0]]; }] description] isEqual: @"{\n\tkey1 = value_1;\n}"]) #endif TEST(@"-[count]", mutableDict.count == 2) TEST(@"+[dictionaryWithKeysAndObjects:]", (dict = [dictionaryClass dictionaryWithKeysAndObjects: @"foo", @"bar", @"baz", @"qux", nil]) && [[dict objectForKey: @"foo"] isEqual: @"bar"] && [[dict objectForKey: @"baz"] isEqual: @"qux"]) |
︙ | ︙ | |||
355 356 357 358 359 360 361 | TEST(@"-[copy]", (dict = [[dict copy] autorelease]) && [[dict objectForKey: keys[0]] isEqual: values[0]] && [[dict objectForKey: keys[1]] isEqual: values[1]]) TEST(@"-[mutableCopy]", | | | | | | < | | | < | | | | < | | | | < | | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | TEST(@"-[copy]", (dict = [[dict copy] autorelease]) && [[dict objectForKey: keys[0]] isEqual: values[0]] && [[dict objectForKey: keys[1]] isEqual: values[1]]) TEST(@"-[mutableCopy]", (mutableDict = [[dict mutableCopy] autorelease]) && mutableDict.count == dict.count && [[mutableDict objectForKey: keys[0]] isEqual: values[0]] && [[mutableDict objectForKey: keys[1]] isEqual: values[1]] && R([mutableDict setObject: @"value3" forKey: @"key3"]) && [[mutableDict objectForKey: @"key3"] isEqual: @"value3"] && [[mutableDict objectForKey: keys[0]] isEqual: values[0]] && R([mutableDict setObject: @"foo" forKey: keys[0]]) && [[mutableDict objectForKey: keys[0]] isEqual: @"foo"]) TEST(@"-[removeObjectForKey:]", R([mutableDict removeObjectForKey: keys[0]]) && [mutableDict objectForKey: keys[0]] == nil) [mutableDict setObject: @"foo" forKey: keys[0]]; TEST(@"-[isEqual:]", ![mutableDict isEqual: dict] && R([mutableDict removeObjectForKey: @"key3"]) && ![mutableDict isEqual: dict] && R([mutableDict setObject: values[0] forKey: keys[0]]) && [mutableDict isEqual: dict]) objc_autoreleasePoolPop(pool); } - (void)dictionaryTests { module = @"OFDictionary"; |
︙ | ︙ |
Modified tests/OFHMACTests.m from [ee4f6f3a73] to [7c5227bed5].
1 | /* | < < | | | | | | | | | | < | | | | | | | | | | | | | | | | | < | < | < | < | < | < | | | < | < | < | < | < | < | < | > > > > > > > | | | | | < | < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFHMAC"; static const uint8_t key[] = "yM9h8K6IWnJRvxC/0F8XRWG7RnACDBz8wqK2tbXrYVLoKC3vPLeJikyJSM47tVHc" "DlXHww9zULAC2sJUlm2Kg1z4oz2aXY3Y1PQSB4VkC/m0DQ7hCI6cAg4TWnKdzWTy" "cvYGX+Y6HWeDY79/PGSd8fNItme6I8w4HDBqU7BP2sum3jbePJqoiSnhcyJZQTeZ" "jw0ZXoyrfHgOYD2M+NsTDaGpLblFtQ7n5CczjKtafG40PkEwx1dcrd46U9i3GyTK"; static const size_t keyLength = sizeof(key); static const uint8_t MD5Digest[] = "\xCC\x1F\xEF\x09\x29\xA3\x25\x1A\x06\xA9\x83\x99\xF9\xBC\x8F\x42"; static const uint8_t SHA1Digest[] = "\x94\xB9\x0A\x6F\xFB\xA7\x13\x6A\x75\x55" "\xD5\x7F\x5D\xB7\xF4\xCA\xEB\x4A\xDE\xBF"; static const uint8_t RIPEMD160Digest[] = "\x2C\xE1\xED\x41\xC6\xF3\x51\xA8\x04\xD2" "\xC3\x9B\x08\x33\x3B\xD5\xC9\x00\x39\x50"; static const uint8_t SHA256Digest[] = "\xFB\x8C\xDA\x88\xB3\x81\x32\x16\xD7\xD8\x62\xD4\xA6\x26\x9D\x77" "\x01\x99\x62\x65\x29\x02\x41\xE6\xEF\xA1\x02\x31\xA8\x9D\x77\x5D"; static const uint8_t SHA384Digest[] = "\x2F\x4A\x47\xAE\x13\x8E\x96\x52\xF1\x8F\x05\xFD\x65\xCD\x9A\x97" "\x93\x2F\xC9\x02\xD6\xC6\xAB\x2E\x15\x76\xC0\xA7\xA0\x05\xF4\xEF" "\x14\x52\x33\x4B\x9C\x5F\xD8\x07\x4E\x98\xAE\x97\x46\x29\x24\xB4"; static const uint8_t SHA512Digest[] = "\xF5\x8C\x3F\x9C\xA2\x2F\x0A\xF3\x26\xD8\xC0\x7E\x20\x63\x88\x61" "\xC9\xE1\x1F\xD7\xC7\xE5\x59\x33\xD5\x2F\xAF\x56\x1C\x94\xC8\xA4" "\x61\xB3\xF9\x1A\xE3\x09\x43\xA6\x5B\x85\xB1\x50\x5B\xCB\x1A\x2E" "\xB7\xE8\x87\xC1\x73\x19\x63\xF6\xA2\x91\x8D\x7E\x2E\xCC\xEC\x99"; @implementation TestsAppDelegate (OFHMACTests) - (void)HMACTests { void *pool = objc_autoreleasePoolPush(); OFFile *file = [OFFile fileWithPath: @"testfile.bin" mode: @"r"]; OFHMAC *HMACMD5, *HMACSHA1, *HMACRMD160; OFHMAC *HMACSHA256, *HMACSHA384, *HMACSHA512; TEST(@"+[HMACWithHashClass:] with MD5", (HMACMD5 = [OFHMAC HMACWithHashClass: [OFMD5Hash class] allowsSwappableMemory: true])) TEST(@"+[HMACWithHashClass:] with SHA-1", (HMACSHA1 = [OFHMAC HMACWithHashClass: [OFSHA1Hash class] allowsSwappableMemory: true])) TEST(@"+[HMACWithHashClass:] with RIPEMD-160", (HMACRMD160 = [OFHMAC HMACWithHashClass: [OFRIPEMD160Hash class] allowsSwappableMemory: true])) TEST(@"+[HMACWithHashClass:] with SHA-256", (HMACSHA256 = [OFHMAC HMACWithHashClass: [OFSHA256Hash class] allowsSwappableMemory: true])) TEST(@"+[HMACWithHashClass:] with SHA-384", (HMACSHA384 = [OFHMAC HMACWithHashClass: [OFSHA384Hash class] allowsSwappableMemory: true])) TEST(@"+[HMACWithHashClass:] with SHA-512", (HMACSHA512 = [OFHMAC HMACWithHashClass: [OFSHA512Hash class] allowsSwappableMemory: true])) EXPECT_EXCEPTION(@"Detection of missing key", OFInvalidArgumentException, [HMACMD5 updateWithBuffer: "" length: 0]) TEST(@"-[setKey:length:] with MD5", R([HMACMD5 setKey: key length: keyLength])) TEST(@"-[setKey:length:] with SHA-1", R([HMACSHA1 setKey: key length: keyLength])) TEST(@"-[setKey:length:] with RIPEMD-160", R([HMACRMD160 setKey: key length: keyLength])) TEST(@"-[setKey:length:] with SHA-256", R([HMACSHA256 setKey: key length: keyLength])) TEST(@"-[setKey:length:] with SHA-384", R([HMACSHA384 setKey: key length: keyLength])) TEST(@"-[setKey:length:] with SHA-512", R([HMACSHA512 setKey: key length: keyLength])) while (!file.atEndOfStream) { char buffer[64]; size_t length = [file readIntoBuffer: buffer length: 64]; [HMACMD5 updateWithBuffer: buffer length: length]; [HMACSHA1 updateWithBuffer: buffer length: length]; [HMACRMD160 updateWithBuffer: buffer length: length]; [HMACSHA256 updateWithBuffer: buffer length: length]; [HMACSHA384 updateWithBuffer: buffer length: length]; [HMACSHA512 updateWithBuffer: buffer length: length]; } [file close]; TEST(@"-[calculate] with MD5", R([HMACMD5 calculate])) TEST(@"-[calculate] with SHA-1", R([HMACSHA1 calculate])) TEST(@"-[calculate] with RIPEMD-160", R([HMACRMD160 calculate])) TEST(@"-[calculate] with SHA-256", R([HMACSHA256 calculate])) TEST(@"-[calculate] with SHA-384", R([HMACSHA384 calculate])) TEST(@"-[calculate] with SHA-512", R([HMACSHA512 calculate])) TEST(@"-[digest] with MD5", memcmp(HMACMD5.digest, MD5Digest, HMACMD5.digestSize) == 0) TEST(@"-[digest] with SHA-1", memcmp(HMACSHA1.digest, SHA1Digest, HMACSHA1.digestSize) == 0) TEST(@"-[digest] with RIPEMD-160", memcmp(HMACRMD160.digest, RIPEMD160Digest, HMACRMD160.digestSize) == 0) TEST(@"-[digest] with SHA-256", memcmp(HMACSHA256.digest, SHA256Digest, HMACSHA256.digestSize) == 0) TEST(@"-[digest] with SHA-384", memcmp(HMACSHA384.digest, SHA384Digest, HMACSHA384.digestSize) == 0) TEST(@"-[digest] with SHA-512", memcmp(HMACSHA512.digest, SHA512Digest, HMACSHA512.digestSize) == 0) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFHTTPClientTests.m from [086ef33868] to [0615ead311].
1 | /* | < < | | | | | < | | | < < | < < | < < | | < | | < | < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <inttypes.h> #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFHTTPClient"; static OFCondition *condition; static OFHTTPResponse *response = nil; @interface TestsAppDelegate (HTTPClientTests) <OFHTTPClientDelegate> @end @interface HTTPClientTestsServer: OFThread { @public uint16_t _port; } @end @implementation HTTPClientTestsServer - (id)main { OFTCPSocket *listener, *client; char buffer[5]; [condition lock]; listener = [OFTCPSocket socket]; _port = [listener bindToHost: @"127.0.0.1" port: 0]; [listener listen]; [condition signal]; [condition unlock]; client = [listener accept]; OFEnsure([[client readLine] isEqual: @"GET /foo HTTP/1.1"]); OFEnsure([[client readLine] hasPrefix: @"User-Agent:"]); OFEnsure([[client readLine] isEqual: @"Content-Length: 5"]); OFEnsure([[client readLine] isEqual: @"Content-Type: application/x-www-form-urlencoded; charset=UTF-8"]); if (![[client readLine] isEqual: [OFString stringWithFormat: @"Host: 127.0.0.1:%" @PRIu16, _port]]) OFEnsure(0); OFEnsure([[client readLine] isEqual: @""]); [client readIntoBuffer: buffer exactLength: 5]; OFEnsure(memcmp(buffer, "Hello", 5) == 0); [client writeString: @"HTTP/1.0 200 OK\r\n" @"cONTeNT-lENgTH: 7\r\n" @"\r\n" @"foo\n" @"bar"]; [client close]; |
︙ | ︙ | |||
99 100 101 102 103 104 105 | } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response_ exception: (id)exception { | | | | | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response_ exception: (id)exception { OFEnsure(exception == nil); response = [response_ retain]; [[OFRunLoop mainRunLoop] stop]; } - (void)HTTPClientTests { void *pool = objc_autoreleasePoolPush(); HTTPClientTestsServer *server; OFURL *URL; OFHTTPClient *client; OFHTTPRequest *request; OFData *data; condition = [OFCondition condition]; [condition lock]; server = [[[HTTPClientTestsServer alloc] init] autorelease]; server.supportsSockets = true; [server start]; [condition wait]; [condition unlock]; URL = [OFURL URLWithString: [OFString stringWithFormat: @"http://127.0.0.1:%" @PRIu16 "/foo", server->_port]]; TEST(@"-[asyncPerformRequest:]", (client = [OFHTTPClient client]) && (client.delegate = self) && |
︙ | ︙ |
Modified tests/OFHTTPCookieManagerTests.m from [0364d9ffbe] to [8647894d6b].
1 | /* | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFHTTPCookieManager"; @implementation TestsAppDelegate (OFHTTPCookieManagerTests) - (void)HTTPCookieManagerTests { void *pool = objc_autoreleasePoolPush(); OFHTTPCookieManager *manager = [OFHTTPCookieManager manager]; OFURL *URL1, *URL2, *URL3, *URL4; OFHTTPCookie *cookie1, *cookie2, *cookie3, *cookie4, *cookie5; URL1 = [OFURL URLWithString: @"http://nil.im/foo"]; URL2 = [OFURL URLWithString: @"https://nil.im/foo/bar"]; URL3 = [OFURL URLWithString: @"https://test.nil.im/foo/bar"]; URL4 = [OFURL URLWithString: @"http://webkeks.org/foo/bar"]; cookie1 = [OFHTTPCookie cookieWithName: @"test" value: @"1" domain: @"nil.im"]; TEST(@"-[addCookie:forURL:] #1", R([manager addCookie: cookie1 forURL: URL1])) TEST(@"-[cookiesForURL:] #1", [[manager cookiesForURL: URL1] isEqual: [OFArray arrayWithObject: cookie1]]) cookie2 = [OFHTTPCookie cookieWithName: @"test" value: @"2" domain: @"webkeks.org"]; TEST(@"-[addCookie:forURL:] #2", R([manager addCookie: cookie2 forURL: URL1])) TEST(@"-[cookiesForURL:] #2", [[manager cookiesForURL: URL1] isEqual: [OFArray arrayWithObject: cookie1]] && [[manager cookiesForURL: URL4] isEqual: [OFArray array]]) cookie3 = [OFHTTPCookie cookieWithName: @"test" value: @"3" domain: @"nil.im"]; cookie3.secure = true; TEST(@"-[addCookie:forURL:] #3", R([manager addCookie: cookie3 forURL: URL2])) TEST(@"-[cookiesForURL:] #3", [[manager cookiesForURL: URL2] isEqual: [OFArray arrayWithObject: cookie3]] && [[manager cookiesForURL: URL1] isEqual: [OFArray array]]) cookie3.expires = [OFDate dateWithTimeIntervalSinceNow: -1]; cookie4 = [OFHTTPCookie cookieWithName: @"test" value: @"4" domain: @"nil.im"]; cookie4.domain = @".nil.im"; TEST(@"-[addCookie:forURL:] #4", R([manager addCookie: cookie4 forURL: URL2])) TEST(@"-[cookiesForURL:] #4", [[manager cookiesForURL: URL2] isEqual: [OFArray arrayWithObject: cookie4]] && [[manager cookiesForURL: URL3] isEqual: [OFArray arrayWithObject: cookie4]]) cookie5 = [OFHTTPCookie cookieWithName: @"bar" value: @"5" domain: @"test.nil.im"]; TEST(@"-[addCookie:forURL:] #5", R([manager addCookie: cookie5 forURL: URL1])) TEST(@"-[cookiesForURL:] #5", [[manager cookiesForURL: URL1] isEqual: [OFArray arrayWithObject: cookie4]] && [[manager cookiesForURL: URL3] isEqual: [OFArray arrayWithObjects: cookie4, cookie5, nil]]) TEST(@"-[purgeExpiredCookies]", [manager.cookies isEqual: [OFArray arrayWithObjects: cookie3, cookie4, cookie5, nil]] && R([manager purgeExpiredCookies]) && [manager.cookies isEqual: [OFArray arrayWithObjects: cookie4, cookie5, nil]]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFHTTPCookieTests.m from [5858023a0b] to [e2e55e8f73].
1 | /* | < < | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFHTTPCookie"; @implementation TestsAppDelegate (OFHTTPCookieTests) - (void)HTTPCookieTests { void *pool = objc_autoreleasePoolPush(); OFURL *URL = [OFURL URLWithString: @"http://nil.im"]; OFHTTPCookie *cookie1, *cookie2; OFArray OF_GENERIC(OFHTTPCookie *) *cookies; cookie1 = [OFHTTPCookie cookieWithName: @"foo" value: @"bar" domain: @"nil.im"]; TEST(@"+[cookiesWithResponseHeaderFields:forURL:] #1", [[OFHTTPCookie cookiesWithResponseHeaderFields: [OFDictionary dictionaryWithObject: @"foo=bar" forKey: @"Set-Cookie"] forURL: URL] isEqual: [OFArray arrayWithObject: cookie1]]) cookie2 = [OFHTTPCookie cookieWithName: @"qux" value: @"cookie" domain: @"nil.im"]; TEST(@"+[cookiesWithResponseHeaderFields:forURL:] #2", [[OFHTTPCookie cookiesWithResponseHeaderFields: [OFDictionary dictionaryWithObject: @"foo=bar,qux=cookie" forKey: @"Set-Cookie"] forURL: URL] isEqual: [OFArray arrayWithObjects: cookie1, cookie2, nil]]) cookie1.expires = [OFDate dateWithTimeIntervalSince1970: 1234567890]; cookie2.expires = [OFDate dateWithTimeIntervalSince1970: 1234567890]; cookie1.path = @"/x"; cookie2.domain = @"webkeks.org"; cookie2.path = @"/objfw"; cookie2.secure = true; cookie2.HTTPOnly = true; [cookie2.extensions addObject: @"foo"]; [cookie2.extensions addObject: @"bar"]; TEST(@"+[cookiesWithResponseHeaderFields:forURL:] #3", [(cookies = [OFHTTPCookie cookiesWithResponseHeaderFields: [OFDictionary dictionaryWithObject: @"foo=bar; Expires=Fri, 13 Feb 2009 23:31:30 GMT; Path=/x," @"qux=cookie; Expires=Fri, 13 Feb 2009 23:31:30 GMT; " @"Domain=webkeks.org; Path=/objfw; Secure; HTTPOnly; foo; bar" forKey: @"Set-Cookie"] forURL: URL]) isEqual: [OFArray arrayWithObjects: cookie1, cookie2, nil]]) TEST(@"+[requestHeaderFieldsWithCookies:]", [[OFHTTPCookie requestHeaderFieldsWithCookies: cookies] isEqual: [OFDictionary dictionaryWithObject: @"foo=bar; qux=cookie" forKey: @"Cookie"]]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFINIFileTests.m from [72a60d0481] to [7188d57b9b].
1 | /* | < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *module; @implementation TestsAppDelegate (OFINIFileTests) - (void)INIFileTests { void *pool = objc_autoreleasePoolPush(); OFString *output = @"[tests]\r\n" @"foo=baz\r\n" |
︙ | ︙ | |||
47 48 49 50 51 52 53 54 55 56 | @"double=0.75\r\n"; OFINIFile *file; OFINICategory *tests, *foobar, *types; OFArray *array; #ifndef OF_NINTENDO_DS OFString *writePath; #endif TEST(@"+[fileWithPath:encoding:]", (file = [OFINIFile fileWithPath: @"testfile.ini" | > > | | < | < | < | < | | | | < | < | < | | | < | | | | | | | | < | < | < < < < | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | @"double=0.75\r\n"; OFINIFile *file; OFINICategory *tests, *foobar, *types; OFArray *array; #ifndef OF_NINTENDO_DS OFString *writePath; #endif module = @"OFINIFile"; TEST(@"+[fileWithPath:encoding:]", (file = [OFINIFile fileWithPath: @"testfile.ini" encoding: OFStringEncodingCodepage437])) tests = [file categoryForName: @"tests"]; foobar = [file categoryForName: @"foobar"]; types = [file categoryForName: @"types"]; TEST(@"-[categoryForName:]", tests != nil && foobar != nil && types != nil) module = @"OFINICategory"; TEST(@"-[stringForKey:]", [[tests stringForKey: @"foo"] isEqual: @"bar"] && [[foobar stringForKey: @"quxquxqux"] isEqual: @"hello\"wörld"]) TEST(@"-[setString:forKey:]", R([tests setString: @"baz" forKey: @"foo"]) && R([tests setString: @"new" forKey: @"new"]) && R([foobar setString: @"a\fb" forKey: @"qux3"])) TEST(@"-[longLongForKey:defaultValue:]", [types longLongForKey: @"integer" defaultValue: 2] == 0x20) TEST(@"-[setLongLong:forKey:]", R([types setLongLong: 0x10 forKey: @"integer"])) TEST(@"-[boolForKey:defaultValue:]", [types boolForKey: @"bool" defaultValue: false] == true) TEST(@"-[setBool:forKey:]", R([types setBool: false forKey: @"bool"])) TEST(@"-[floatForKey:defaultValue:]", [types floatForKey: @"float" defaultValue: 1] == 0.5f) TEST(@"-[setFloat:forKey:]", R([types setFloat: 0.25f forKey: @"float"])) TEST(@"-[doubleForKey:defaultValue:]", [types doubleForKey: @"double" defaultValue: 3] == 0.25) TEST(@"-[setDouble:forKey:]", R([types setDouble: 0.75 forKey: @"double"])) array = [OFArray arrayWithObjects: @"1", @"2", nil]; TEST(@"-[stringArrayForKey:]", [[types stringArrayForKey: @"array1"] isEqual: array] && [[types stringArrayForKey: @"array2"] isEqual: array] && [[types stringArrayForKey: @"array3"] isEqual: [OFArray array]]) array = [OFArray arrayWithObjects: @"foo", @"bar", nil]; TEST(@"-[setStringArray:forKey:]", R([types setStringArray: array forKey: @"array1"])) TEST(@"-[removeValueForKey:]", R([foobar removeValueForKey: @"quxqux "]) && R([types removeValueForKey: @"array2"])) module = @"OFINIFile"; /* FIXME: Find a way to write files on Nintendo DS */ #ifndef OF_NINTENDO_DS writePath = [[OFSystemInfo temporaryDirectoryPath] stringByAppendingPathComponent: @"objfw-tests.ini"]; TEST(@"-[writeToFile:encoding:]", R([file writeToFile: writePath encoding: OFStringEncodingCodepage437]) && [[OFString stringWithContentsOfFile: writePath encoding: OFStringEncodingCodepage437] isEqual: output]) [[OFFileManager defaultManager] removeItemAtPath: writePath]; #else (void)output; #endif objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFIPXSocketTests.m from [a065806b7f] to [4dd5afc6b6].
1 | /* | < < | | | | < | | | | | | | < < | < < | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFIPXSocket"; @implementation TestsAppDelegate (OFIPXSocketTests) - (void)IPXSocketTests { void *pool = objc_autoreleasePoolPush(); OFIPXSocket *sock; OFSocketAddress address1, address2; char buffer[5]; TEST(@"+[socket]", (sock = [OFIPXSocket socket])) @try { TEST(@"-[bindToPort:packetType:]", R(address1 = [sock bindToPort: 0 packetType: 0])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFIPXSocket] -[bindToPort:packetType:]: " @"IPX unsupported, skipping tests"]; break; case EADDRNOTAVAIL: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFIPXSocket] -[bindToPort:packetType:]: " @"IPX not configured, skipping tests"]; break; default: @throw e; } objc_autoreleasePoolPop(pool); return; } TEST(@"-[sendBuffer:length:receiver:]", R([sock sendBuffer: "Hello" length: 5 receiver: &address1])) TEST(@"-[receiveIntoBuffer:length:sender:]", [sock receiveIntoBuffer: buffer length: 5 sender: &address2] == 5 && memcmp(buffer, "Hello", 5) == 0 && OFSocketAddressEqual(&address1, &address2) && OFSocketAddressHash(&address1) == OFSocketAddressHash(&address2)) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFInvocationTests.m from [2e969e8d08] to [bb91b5d725].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | #if defined(HAVE_COMPLEX_H) && !defined(__STDC_NO_COMPLEX__) # include <complex.h> #endif #import "TestsAppDelegate.h" | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #if defined(HAVE_COMPLEX_H) && !defined(__STDC_NO_COMPLEX__) # include <complex.h> #endif #import "TestsAppDelegate.h" static OFString *const module = @"OFInvocation"; struct TestStruct { unsigned char c; unsigned int i; }; @implementation TestsAppDelegate (OFInvocationTests) - (struct TestStruct)invocationTestMethod1: (unsigned char)c : (unsigned int)i : (struct TestStruct *)ptr : (struct TestStruct)st { return st; } - (void)invocationTests { void *pool = objc_autoreleasePoolPush(); SEL selector = @selector(invocationTestMethod1::::); OFMethodSignature *sig = [self methodSignatureForSelector: selector]; OFInvocation *invocation; struct TestStruct st, st2, *stp = &st, *stp2; unsigned const char c = 0xAA; unsigned char c2; const unsigned int i = 0x55555555; unsigned int i2; memset(&st, '\xFF', sizeof(st)); st.c = 0x55; |
︙ | ︙ | |||
281 282 283 284 285 286 287 | TEST(@"-[setReturnValue]", R([invocation setReturnValue: &st])) TEST(@"-[getReturnValue]", R([invocation getReturnValue: &st2]) && memcmp(&st, &st2, sizeof(st)) == 0) memset(&st2, '\0', sizeof(st2)); | | < < | < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < | < < < < < < < < | < < | < | < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < | < < < < < < < < < < < < < < < | < < | < < < < < < < < < < | < < < < < < < < | < < < < | < < < < < < < < < | | < | < < < < < < < < < < < < < < < < < < < < | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | TEST(@"-[setReturnValue]", R([invocation setReturnValue: &st])) TEST(@"-[getReturnValue]", R([invocation getReturnValue: &st2]) && memcmp(&st, &st2, sizeof(st)) == 0) memset(&st2, '\0', sizeof(st2)); TEST(@"-[setArgument:atIndex:] #1", R([invocation setArgument: &c atIndex: 2])) TEST(@"-[setArgument:atIndex:] #2", R([invocation setArgument: &i atIndex: 3])) TEST(@"-[setArgument:atIndex:] #3", R([invocation setArgument: &stp atIndex: 4])) TEST(@"-[setArgument:atIndex:] #4", R([invocation setArgument: &st atIndex: 5])) TEST(@"-[getArgument:atIndex:] #1", R([invocation getArgument: &c2 atIndex: 2]) && c == c2) TEST(@"-[getArgument:atIndex:] #2", R([invocation getArgument: &i2 atIndex: 3]) && i == i2) TEST(@"-[getArgument:atIndex:] #3", R([invocation getArgument: &stp2 atIndex: 4]) && stp == stp2) TEST(@"-[getArgument:atIndex:] #4", R([invocation getArgument: &st2 atIndex: 5]) && memcmp(&st, &st2, sizeof(st)) == 0) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFJSONTests.m from [dda895677f] to [330199594e].
1 | /* | < < | | | | | | | | | | | | > | > | | > | | | | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFJSON"; @implementation TestsAppDelegate (JSONTests) - (void)JSONTests { void *pool = objc_autoreleasePoolPush(); OFString *string = @"{\"foo\"\t:'b\\na\\r', \"x\":/*foo*/ [.5\r,0xF," @"null//bar\n,\"foo\",false]}"; OFDictionary *dict = [OFDictionary dictionaryWithKeysAndObjects: @"foo", @"b\na\r", @"x", [OFArray arrayWithObjects: [OFNumber numberWithFloat: .5f], [OFNumber numberWithInt: 0xF], [OFNull null], @"foo", [OFNumber numberWithBool: false], nil], nil]; TEST(@"-[objectByParsingJSON] #1", [string.objectByParsingJSON isEqual: dict]) TEST(@"-[JSONRepresentation]", [[dict JSONRepresentation] isEqual: @"{\"x\":[0.5,15,null,\"foo\",false],\"foo\":\"b\\na\\r\"}"]) TEST(@"OFJSONRepresentationOptionPretty", [[dict JSONRepresentationWithOptions: OFJSONRepresentationOptionPretty] isEqual: @"{\n\t\"x\": [\n\t\t0.5,\n\t\t15,\n\t\tnull,\n\t\t" @"\"foo\",\n\t\tfalse\n\t],\n\t\"foo\": \"b\\na\\r\"\n}"]) TEST(@"OFJSONRepresentationOptionJSON5", [[dict JSONRepresentationWithOptions: OFJSONRepresentationOptionJSON5] isEqual: @"{x:[0.5,15,null,\"foo\",false],foo:\"b\\\na\\r\"}"]) EXPECT_EXCEPTION(@"-[objectByParsingJSON] #2", OFInvalidJSONException, [@"{" objectByParsingJSON]) EXPECT_EXCEPTION(@"-[objectByParsingJSON] #3", OFInvalidJSONException, [@"]" objectByParsingJSON]) EXPECT_EXCEPTION(@"-[objectByParsingJSON] #4", OFInvalidJSONException, [@"bar" objectByParsingJSON]) |
︙ | ︙ |
Modified tests/OFKernelEventObserverTests.m from [d22c843df2] to [cec268df6c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | #endif #ifdef HAVE_SELECT # import "OFSelectKernelEventObserver.h" #endif #import "TestsAppDelegate.h" | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #endif #ifdef HAVE_SELECT # import "OFSelectKernelEventObserver.h" #endif #import "TestsAppDelegate.h" static const size_t numExpectedEvents = 3; static OFString *module; @interface ObserverTest: OFObject <OFKernelEventObserverDelegate> { @public TestsAppDelegate *_testsAppDelegate; |
︙ | ︙ | |||
56 57 58 59 60 61 62 | @try { uint16_t port; _testsAppDelegate = testsAppDelegate; _server = [[OFTCPSocket alloc] init]; | | < | < < | < | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | @try { uint16_t port; _testsAppDelegate = testsAppDelegate; _server = [[OFTCPSocket alloc] init]; port = [_server bindToHost: @"127.0.0.1" port: 0]; [_server listen]; _client = [[OFTCPSocket alloc] init]; [_client connectToHost: @"127.0.0.1" port: port]; [_client writeBuffer: "0" length: 1]; } @catch (id e) { [self release]; @throw e; } return self; } |
︙ | ︙ | |||
92 93 94 95 96 97 98 | OFDate *deadline; bool deadlineExceeded = false; [_testsAppDelegate outputTesting: @"-[observe] with listening socket" inModule: module]; deadline = [OFDate dateWithTimeIntervalSinceNow: 1]; | | | | | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | OFDate *deadline; bool deadlineExceeded = false; [_testsAppDelegate outputTesting: @"-[observe] with listening socket" inModule: module]; deadline = [OFDate dateWithTimeIntervalSinceNow: 1]; while (_events < numExpectedEvents) { if (deadline.timeIntervalSinceNow < 0) { deadlineExceeded = true; break; } [_observer observeForTimeInterval: 0.01]; } if (!deadlineExceeded) [_testsAppDelegate outputSuccess: @"-[observe] not exceeding deadline" inModule: module]; else { [_testsAppDelegate outputFailure: @"-[observe] not exceeding deadline" inModule: module]; _fails++; } if (_events == numExpectedEvents) [_testsAppDelegate outputSuccess: @"-[observe] handling all events" inModule: module]; else { [_testsAppDelegate outputFailure: @"-[observe] handling all events" inModule: module]; _fails++; } } - (void)objectIsReadyForReading: (id)object { char buffer; switch (_events++) { case 0: if (object == _server) [_testsAppDelegate outputSuccess: @"-[observe] with listening socket" inModule: module]; |
︙ | ︙ | |||
151 152 153 154 155 156 157 | [_testsAppDelegate outputTesting: @"-[observe] with data ready to read" inModule: module]; break; case 1: if (object == _accepted && | | | | < | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | [_testsAppDelegate outputTesting: @"-[observe] with data ready to read" inModule: module]; break; case 1: if (object == _accepted && [object readIntoBuffer: &buffer length: 1] == 1 && buffer == '0') [_testsAppDelegate outputSuccess: @"-[observe] with data ready to read" inModule: module]; else { [_testsAppDelegate outputFailure: @"-[observe] with data ready to read" inModule: module]; _fails++; } [_client close]; [_testsAppDelegate outputTesting: @"-[observe] with closed connection" inModule: module]; break; case 2: if (object == _accepted && [object readIntoBuffer: &buffer length: 1] == 0) [_testsAppDelegate outputSuccess: @"-[observe] with closed connection" inModule: module]; else { [_testsAppDelegate outputFailure: @"-[observe] with closed connection" inModule: module]; _fails++; } break; default: OFEnsure(0); } } @end @implementation TestsAppDelegate (OFKernelEventObserverTests) - (void)kernelEventObserverTestsWithClass: (Class)class { |
︙ | ︙ |
Modified tests/OFListTests.m from [21b92f7bc2] to [43f56ef79d].
1 | /* | < < | | | | | | | > | | | | > | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFList"; static OFString *strings[] = { @"Foo", @"Bar", @"Baz" }; @implementation TestsAppDelegate (OFListTests) - (void)listTests { void *pool = objc_autoreleasePoolPush(); OFList *list; OFEnumerator *enumerator; OFListItem iter; OFString *object; size_t i; bool ok; TEST(@"+[list]", (list = [OFList list])) TEST(@"-[appendObject:]", [list appendObject: strings[0]] && [list appendObject: strings[1]] && [list appendObject: strings[2]]) TEST(@"-[firstListItem]", [OFListItemObject(list.firstListItem) isEqual: strings[0]]) TEST(@"OFListItemNext()", [OFListItemObject(OFListItemNext(list.firstListItem)) isEqual: strings[1]]) TEST(@"-[lastListItem]", [OFListItemObject(list.lastListItem) isEqual: strings[2]]) TEST(@"OFListItemPrevious()", [OFListItemObject(OFListItemPrevious(list.lastListItem)) isEqual: strings[1]]) TEST(@"-[removeListItem:]", R([list removeListItem: list.lastListItem]) && [list.lastObject isEqual: strings[1]] && R([list removeListItem: list.firstListItem]) && [list.firstObject isEqual: list.lastObject]) TEST(@"-[insertObject:beforeListItem:]", [list insertObject: strings[0] beforeListItem: list.lastListItem] && [OFListItemObject(OFListItemPrevious(list.lastListItem)) isEqual: strings[0]]) TEST(@"-[insertObject:afterListItem:]", [list insertObject: strings[2] afterListItem: OFListItemNext(list.firstListItem)] && [list.lastObject isEqual: strings[2]]) TEST(@"-[count]", list.count == 3) TEST(@"-[containsObject:]", [list containsObject: strings[1]] && ![list containsObject: @"nonexistent"]) TEST(@"-[containsObjectIdenticalTo:]", [list containsObjectIdenticalTo: strings[1]] && ![list containsObjectIdenticalTo: [OFString stringWithString: strings[1]]]) TEST(@"-[copy]", (list = [[list copy] autorelease]) && [list.firstObject isEqual: strings[0]] && [OFListItemObject(OFListItemNext(list.firstListItem)) isEqual: strings[1]] && [list.lastObject isEqual: strings[2]]) TEST(@"-[isEqual:]", [list isEqual: [[list copy] autorelease]]) TEST(@"-[description]", [list.description isEqual: @"[\n\tFoo,\n\tBar,\n\tBaz\n]"]) TEST(@"-[objectEnumerator]", (enumerator = [list objectEnumerator])) iter = list.firstListItem; i = 0; ok = true; while ((object = [enumerator nextObject]) != nil) { if (![object isEqual: OFListItemObject(iter)]) ok = false; iter = OFListItemNext(iter); i++; } if (list.count != i) ok = false; TEST(@"OFEnumerator's -[nextObject]", ok); [list removeListItem: list.firstListItem]; EXPECT_EXCEPTION(@"Detection of mutation during enumeration", OFEnumerationMutationException, [enumerator nextObject]) [list prependObject: strings[0]]; iter = list.firstListItem; i = 0; ok = true; for (OFString *object_ in list) { if (![object_ isEqual: OFListItemObject(iter)]) ok = false; iter = OFListItemNext(iter); i++; } if (list.count != i) ok = false; TEST(@"Fast Enumeration", ok) ok = false; @try { for (OFString *object_ in list) { (void)object_; [list removeListItem: list.lastListItem]; } } @catch (OFEnumerationMutationException *e) { ok = true; } TEST(@"Detection of mutation during Fast Enumeration", ok) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFLocaleTests.m from [dbaa1191c5] to [08f116fb95].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 | #import "TestsAppDelegate.h" @implementation TestsAppDelegate (OFLocaleTests) - (void)localeTests { void *pool = objc_autoreleasePoolPush(); | | | | | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #import "TestsAppDelegate.h" @implementation TestsAppDelegate (OFLocaleTests) - (void)localeTests { void *pool = objc_autoreleasePoolPush(); [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeFormat: @"[OFLocale] Language: %@\n", [OFLocale language]]; [OFStdOut writeFormat: @"[OFLocale] Territory: %@\n", [OFLocale territory]]; [OFStdOut writeFormat: @"[OFLocale] Encoding: %@\n", OFStringEncodingName([OFLocale encoding])]; [OFStdOut writeFormat: @"[OFLocale] Decimal point: %@\n", [OFLocale decimalPoint]]; objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFMD5HashTests.m from [ab5377abbe] to [6eb26d1d7b].
1 | /* | < < | | | | | | < | | | | | < | < | | > > | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFMD5Hash"; const uint8_t testFileMD5[16] = "\x00\x8B\x9D\x1B\x58\xDF\xF8\xFE\xEE\xF3\xAE\x8D\xBB\x68\x2D\x38"; @implementation TestsAppDelegate (OFMD5HashTests) - (void)MD5HashTests { void *pool = objc_autoreleasePoolPush(); OFMD5Hash *MD5, *MD5Copy; OFFile *file = [OFFile fileWithPath: @"testfile.bin" mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (MD5 = [OFMD5Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { char buffer[64]; size_t length = [file readIntoBuffer: buffer length: 64]; [MD5 updateWithBuffer: buffer length: length]; } [file close]; TEST(@"-[copy]", (MD5Copy = [[MD5 copy] autorelease])) TEST(@"-[calculate]", R([MD5 calculate]) && R([MD5Copy calculate])) TEST(@"-[digest]", memcmp(MD5.digest, testFileMD5, 16) == 0 && memcmp(MD5Copy.digest, testFileMD5, 16) == 0) EXPECT_EXCEPTION(@"Detect invalid call of " @"-[updateWithBuffer:length]", OFHashAlreadyCalculatedException, [MD5 updateWithBuffer: "" length: 1]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFMethodSignatureTests.m from [9cc11e0ceb] to [8b3d41a60c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | #if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) # include <complex.h> #endif #import "TestsAppDelegate.h" | | | | | | | | | | > | | | | | > | | | | | | > | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | #if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) # include <complex.h> #endif #import "TestsAppDelegate.h" static OFString *const module = @"OFMethodSignature"; struct Test1Struct { char c; int i; char d; }; struct Test2Struct { char c; struct { short s; int i; } st; union { char c; int i; } u; double d; }; #if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) struct Test3Struct { char c; complex double cd; }; #endif union Test3Union { char c; int i; double d; }; union Test4Union { char c; struct { short x, y; } st; int i; union { float f; double d; } u; }; @implementation TestsAppDelegate (OFMethodSignatureTests) - (void)methodSignatureTests { void *pool = objc_autoreleasePoolPush(); OFMethodSignature *methodSignature; TEST(@"-[signatureWithObjCTypes:] #1", (methodSignature = [OFMethodSignature signatureWithObjCTypes: "i28@0:8S16*20"]) && methodSignature.numberOfArguments == 4 && strcmp(methodSignature.methodReturnType, "i") == 0 && strcmp([methodSignature argumentTypeAtIndex: 0], "@") == 0 && strcmp([methodSignature argumentTypeAtIndex: 1], ":") == 0 && strcmp([methodSignature argumentTypeAtIndex: 2], "S") == 0 && strcmp([methodSignature argumentTypeAtIndex: 3], "*") == 0 && methodSignature.frameLength == 28 && [methodSignature argumentOffsetAtIndex: 0] == 0 && [methodSignature argumentOffsetAtIndex: 1] == 8 && [methodSignature argumentOffsetAtIndex: 2] == 16 && [methodSignature argumentOffsetAtIndex: 3] == 20) TEST(@"-[signatureWithObjCTypes:] #2", (methodSignature = [OFMethodSignature signatureWithObjCTypes: "{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}24@0:8" "^{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}16"]) && methodSignature.numberOfArguments == 3 && strcmp(methodSignature.methodReturnType, "{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}") == 0 && strcmp([methodSignature argumentTypeAtIndex: 0], "@") == 0 && strcmp([methodSignature argumentTypeAtIndex: 1], ":") == 0 && strcmp([methodSignature argumentTypeAtIndex: 2], "^{s0=csi(u1={s2=iii{s3=(u4=ic^v*)}})}") == 0 && methodSignature.frameLength == 24 && [methodSignature argumentOffsetAtIndex: 0] == 0 && [methodSignature argumentOffsetAtIndex: 1] == 8 && [methodSignature argumentOffsetAtIndex: 2] == 16) EXPECT_EXCEPTION(@"-[signatureWithObjCTypes:] #3", OFInvalidFormatException, [OFMethodSignature signatureWithObjCTypes: "{ii"]) EXPECT_EXCEPTION(@"-[signatureWithObjCTypes:] #4", OFInvalidFormatException, [OFMethodSignature signatureWithObjCTypes: ""]) EXPECT_EXCEPTION(@"-[signatureWithObjCTypes:] #5", OFInvalidFormatException, [OFMethodSignature signatureWithObjCTypes: "0"]) EXPECT_EXCEPTION(@"-[signatureWithObjCTypes:] #6", OFInvalidFormatException, [OFMethodSignature signatureWithObjCTypes: "{{}0"]) TEST(@"OFSizeOfTypeEncoding() #1", OFSizeOfTypeEncoding(@encode(struct Test1Struct)) == sizeof(struct Test1Struct)) TEST(@"OFSizeOfTypeEncoding() #2", OFSizeOfTypeEncoding(@encode(struct Test2Struct)) == sizeof(struct Test2Struct)) #if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) && \ OF_GCC_VERSION >= 402 TEST(@"OFSizeOfTypeEncoding() #3", OFSizeOfTypeEncoding(@encode(struct Test3Struct)) == sizeof(struct Test3Struct)) #endif TEST(@"OFSizeOfTypeEncoding() #4", OFSizeOfTypeEncoding(@encode(union Test3Union)) == sizeof(union Test3Union)) TEST(@"OFSizeOfTypeEncoding() #5", OFSizeOfTypeEncoding(@encode(union Test4Union)) == sizeof(union Test4Union)) TEST(@"OFSizeOfTypeEncoding() #6", OFSizeOfTypeEncoding(@encode(struct Test1Struct [5])) == sizeof(struct Test1Struct [5])) TEST(@"OFAlignmentOfTypeEncoding() #1", OFAlignmentOfTypeEncoding(@encode(struct Test1Struct)) == OF_ALIGNOF(struct Test1Struct)) TEST(@"OFAlignmentOfTypeEncoding() #2", OFAlignmentOfTypeEncoding(@encode(struct Test2Struct)) == OF_ALIGNOF(struct Test2Struct)) #if !defined(__STDC_NO_COMPLEX__) && defined(HAVE_COMPLEX_H) && \ OF_GCC_VERSION >= 402 TEST(@"OFAlignmentOfTypeEncoding() #3", OFAlignmentOfTypeEncoding(@encode(struct Test3Struct)) == OF_ALIGNOF(struct Test3Struct)) #endif TEST(@"OFAlignmentOfTypeEncoding() #4", OFAlignmentOfTypeEncoding(@encode(union Test3Union)) == OF_ALIGNOF(union Test3Union)) TEST(@"OFAlignmentOfTypeEncoding() #5", OFAlignmentOfTypeEncoding(@encode(union Test4Union)) == OF_ALIGNOF(union Test4Union)) TEST(@"OFAlignmentOfTypeEncoding() #6", OFAlignmentOfTypeEncoding(@encode(struct Test1Struct [5])) == OF_ALIGNOF(struct Test1Struct [5])) objc_autoreleasePoolPop(pool); } @end |
Added tests/OFNotificationCenterTests.m version [4d3ddfb6ba].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFNotificationCenter"; static const OFNotificationName notificationName = @"OFNotificationCenterTestName"; static const OFNotificationName otherNotificationName = @"OFNotificationCenterTestOtherName"; @interface OFNotificationCenterTest: OFObject { @public id _expectedObject; int _received; } - (void)handleNotification: (OFNotification *)notification; @end @implementation OFNotificationCenterTest - (void)handleNotification: (OFNotification *)notification { OFEnsure([notification.name isEqual: notificationName]); OFEnsure(_expectedObject == nil || notification.object == _expectedObject); _received++; } @end @implementation TestsAppDelegate (OFNotificationCenterTests) - (void)notificationCenterTests { void *pool = objc_autoreleasePoolPush(); OFNotificationCenter *center = [OFNotificationCenter defaultCenter]; OFNotificationCenterTest *test1, *test2, *test3, *test4; OFNotification *notification; test1 = [[[OFNotificationCenterTest alloc] init] autorelease]; test1->_expectedObject = self; test2 = [[[OFNotificationCenterTest alloc] init] autorelease]; test3 = [[[OFNotificationCenterTest alloc] init] autorelease]; test3->_expectedObject = self; test4 = [[[OFNotificationCenterTest alloc] init] autorelease]; /* First one intentionally added twice to test deduplication. */ TEST(@"-[addObserver:selector:name:object:]", R([center addObserver: test1 selector: @selector(handleNotification:) name: notificationName object: self]) && R([center addObserver: test1 selector: @selector(handleNotification:) name: notificationName object: self]) && R([center addObserver: test2 selector: @selector(handleNotification:) name: notificationName object: nil]) && R([center addObserver: test3 selector: @selector(handleNotification:) name: otherNotificationName object: self]) && R([center addObserver: test4 selector: @selector(handleNotification:) name: otherNotificationName object: nil])) notification = [OFNotification notificationWithName: notificationName object: nil]; TEST(@"-[postNotification:] #1", R([center postNotification: notification]) && test1->_received == 0 && test2->_received == 1 && test3->_received == 0 && test4->_received == 0) notification = [OFNotification notificationWithName: notificationName object: self]; TEST(@"-[postNotification:] #2", R([center postNotification: notification]) && test1->_received == 1 && test2->_received == 2 && test3->_received == 0 && test4->_received == 0) notification = [OFNotification notificationWithName: notificationName object: @"foo"]; TEST(@"-[postNotification:] #3", R([center postNotification: notification]) && test1->_received == 1 && test2->_received == 3 && test3->_received == 0 && test4->_received == 0) #ifdef OF_HAVE_BLOCKS __block bool received = false; OFNotificationCenterHandle *handle; notification = [OFNotification notificationWithName: notificationName object: self]; TEST(@"-[addObserverForName:object:usingBlock:]", (handle = [center addObserverForName: notificationName object: self usingBlock: ^ (OFNotification *notif) { OFEnsure(notif == notification && !received); received = true; }]) && R([center postNotification: notification]) && received && test1->_received == 2 && test2->_received == 4 && test3->_received == 0 && test4->_received == 0) /* Act like the block test didn't happen. */ [center removeObserver: handle]; test1->_received--; test2->_received--; #endif TEST(@"-[removeObserver:selector:name:object:]", R([center removeObserver: test1 selector: @selector(handleNotification:) name: notificationName object: self]) && R([center removeObserver: test2 selector: @selector(handleNotification:) name: notificationName object: nil]) && R([center removeObserver: test3 selector: @selector(handleNotification:) name: otherNotificationName object: self]) && R([center removeObserver: test4 selector: @selector(handleNotification:) name: otherNotificationName object: nil])) notification = [OFNotification notificationWithName: notificationName object: self]; TEST(@"-[postNotification:] with no observers", R([center postNotification: notification]) && test1->_received == 1 && test2->_received == 3 && test3->_received == 0 && test4->_received == 0) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFNumberTests.m from [c5bef94b63] to [c4180587af].
1 | /* | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFNumber"; @implementation TestsAppDelegate (OFNumberTests) - (void)numberTests { void *pool = objc_autoreleasePoolPush(); OFNumber *number; TEST(@"+[numberWithLongLong:]", (number = [OFNumber numberWithLongLong: 123456789])) TEST(@"-[isEqual:]", [number isEqual: [OFNumber numberWithLong: 123456789]]) TEST(@"-[hash]", number.hash == 0x82D8BC42) TEST(@"-[charValue]", number.charValue == 21) TEST(@"-[doubleValue]", number.doubleValue == 123456789.L) TEST(@"signed char minimum & maximum unmodified", (number = [OFNumber numberWithChar: SCHAR_MIN]) && number.charValue == SCHAR_MIN && (number = [OFNumber numberWithChar: SCHAR_MAX]) && number.charValue == SCHAR_MAX) TEST(@"short minimum & maximum unmodified", (number = [OFNumber numberWithShort: SHRT_MIN]) && number.shortValue == SHRT_MIN && (number = [OFNumber numberWithShort: SHRT_MAX]) && number.shortValue == SHRT_MAX) TEST(@"int minimum & maximum unmodified", (number = [OFNumber numberWithInt: INT_MIN]) && number.intValue == INT_MIN && (number = [OFNumber numberWithInt: INT_MAX]) && number.intValue == INT_MAX) TEST(@"long minimum & maximum unmodified", (number = [OFNumber numberWithLong: LONG_MIN]) && number.longValue == LONG_MIN && (number = [OFNumber numberWithLong: LONG_MAX]) && number.longValue == LONG_MAX) TEST(@"long long minimum & maximum unmodified", (number = [OFNumber numberWithLongLong: LLONG_MIN]) && number.longLongValue == LLONG_MIN && (number = [OFNumber numberWithLongLong: LLONG_MAX]) && number.longLongValue == LLONG_MAX) TEST(@"unsigned char maximum unmodified", (number = [OFNumber numberWithUnsignedChar: UCHAR_MAX]) && number.unsignedCharValue == UCHAR_MAX) TEST(@"unsigned short maximum unmodified", (number = [OFNumber numberWithUnsignedShort: USHRT_MAX]) && number.unsignedShortValue == USHRT_MAX) TEST(@"unsigned int maximum unmodified", (number = [OFNumber numberWithUnsignedInt: UINT_MAX]) && number.unsignedIntValue == UINT_MAX) TEST(@"unsigned long maximum unmodified", (number = [OFNumber numberWithUnsignedLong: ULONG_MAX]) && number.unsignedLongValue == ULONG_MAX) TEST(@"unsigned long long maximum unmodified", (number = [OFNumber numberWithUnsignedLongLong: ULLONG_MAX]) && number.unsignedLongLongValue == ULLONG_MAX) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFObjectTests.m from [5ded62534c] to [fcfeee4a72].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
21 22 23 24 25 26 27 | #if (defined(OF_DRAGONFLYBSD) && defined(__LP64__)) || defined(OF_NINTENDO_3DS) # define TOO_BIG (SIZE_MAX / 3) #else # define TOO_BIG (SIZE_MAX - 128) #endif | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #if (defined(OF_DRAGONFLYBSD) && defined(__LP64__)) || defined(OF_NINTENDO_3DS) # define TOO_BIG (SIZE_MAX / 3) #else # define TOO_BIG (SIZE_MAX - 128) #endif static OFString *const module = @"OFObject"; @interface MyObject: OFObject { id _objectValue; Class _classValue; bool _boolValue; char _charValue; short _shortValue; int _intValue; |
︙ | ︙ | |||
59 60 61 62 63 64 65 | @property (nonatomic) unsigned int unsignedIntValue; @property (nonatomic) unsigned long unsignedLongValue; @property (nonatomic) unsigned long long unsignedLongLongValue; @property (nonatomic) float floatValue; @property (nonatomic) double doubleValue; @end | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | @property (nonatomic) unsigned int unsignedIntValue; @property (nonatomic) unsigned long unsignedLongValue; @property (nonatomic) unsigned long long unsignedLongLongValue; @property (nonatomic) float floatValue; @property (nonatomic) double doubleValue; @end @implementation MyObject @synthesize objectValue = _objectValue, classValue = _classValue; @synthesize boolValue = _boolValue, charValue = _charValue; @synthesize shortValue = _shortValue, intValue = _intValue; @synthesize longValue = _longValue, longLongValue = _longLongValue; @synthesize unsignedCharValue = _unsignedCharValue; @synthesize unsignedShortValue = _unsignedShortValue; @synthesize unsignedIntValue = _unsignedIntValue; |
︙ | ︙ | |||
83 84 85 86 87 88 89 | } @end @implementation TestsAppDelegate (OFObjectTests) - (void)objectTests { void *pool = objc_autoreleasePoolPush(); | < < | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | | | | | | | < | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | > | > | | > | | | | | | | | | | | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | } @end @implementation TestsAppDelegate (OFObjectTests) - (void)objectTests { void *pool = objc_autoreleasePoolPush(); OFObject *object; MyObject *myObject; TEST(@"+[description]", [[OFObject description] isEqual: @"OFObject"] && [[MyObject description] isEqual: @"MyObject"]) object = [[[OFObject alloc] init] autorelease]; myObject = [[[MyObject alloc] init] autorelease]; TEST(@"-[description]", [object.description isEqual: @"<OFObject>"] && [myObject.description isEqual: @"<MyObject>"]) myObject.objectValue = @"Hello"; myObject.classValue = myObject.class; TEST(@"-[valueForKey:]", [[myObject valueForKey: @"objectValue"] isEqual: @"Hello"] && [[myObject valueForKey: @"classValue"] isEqual: myObject.class] && [[myObject valueForKey: @"class"] isEqual: myObject.class]) EXPECT_EXCEPTION(@"-[valueForKey:] with undefined key", OFUndefinedKeyException, [myObject valueForKey: @"undefined"]) TEST(@"-[setValue:forKey:]", R([myObject setValue: @"World" forKey: @"objectValue"]) && R([myObject setValue: [OFObject class] forKey: @"classValue"]) && [myObject.objectValue isEqual: @"World"] && [myObject.classValue isEqual: [OFObject class]]) EXPECT_EXCEPTION(@"-[setValue:forKey:] with undefined key", OFUndefinedKeyException, [myObject setValue: @"x" forKey: @"undefined"]) myObject.boolValue = 1; myObject.charValue = 2; myObject.shortValue = 3; myObject.intValue = 4; myObject.longValue = 5; myObject.longLongValue = 6; myObject.unsignedCharValue = 7; myObject.unsignedShortValue = 8; myObject.unsignedIntValue = 9; myObject.unsignedLongValue = 10; myObject.unsignedLongLongValue = 11; myObject.floatValue = 12; myObject.doubleValue = 13; TEST(@"Auto-wrapping of -[valueForKey:]", [[myObject valueForKey: @"boolValue"] isEqual: [OFNumber numberWithBool: 1]] && [[myObject valueForKey: @"charValue"] isEqual: [OFNumber numberWithChar: 2]] && [[myObject valueForKey: @"shortValue"] isEqual: [OFNumber numberWithShort: 3]] && [[myObject valueForKey: @"intValue"] isEqual: [OFNumber numberWithInt: 4]] && [[myObject valueForKey: @"longValue"] isEqual: [OFNumber numberWithLong: 5]] && [[myObject valueForKey: @"longLongValue"] isEqual: [OFNumber numberWithLongLong: 6]] && [[myObject valueForKey: @"unsignedCharValue"] isEqual: [OFNumber numberWithUnsignedChar: 7]] && [[myObject valueForKey: @"unsignedShortValue"] isEqual: [OFNumber numberWithUnsignedShort: 8]] && [[myObject valueForKey: @"unsignedIntValue"] isEqual: [OFNumber numberWithUnsignedInt: 9]] && [[myObject valueForKey: @"unsignedLongValue"] isEqual: [OFNumber numberWithUnsignedLong: 10]] && [[myObject valueForKey: @"unsignedLongLongValue"] isEqual: [OFNumber numberWithUnsignedLongLong: 11]] && [[myObject valueForKey: @"floatValue"] isEqual: [OFNumber numberWithFloat: 12]] && [[myObject valueForKey: @"doubleValue"] isEqual: [OFNumber numberWithDouble: 13]]) TEST(@"Auto-wrapping of -[setValue:forKey:]", R([myObject setValue: [OFNumber numberWithBool: 0] forKey: @"boolValue"]) && R([myObject setValue: [OFNumber numberWithChar: 10] forKey: @"charValue"]) && R([myObject setValue: [OFNumber numberWithShort: 20] forKey: @"shortValue"]) && R([myObject setValue: [OFNumber numberWithInt: 30] forKey: @"intValue"]) && R([myObject setValue: [OFNumber numberWithLong: 40] forKey: @"longValue"]) && R([myObject setValue: [OFNumber numberWithLongLong: 50] forKey: @"longLongValue"]) && R([myObject setValue: [OFNumber numberWithUnsignedChar: 60] forKey: @"unsignedCharValue"]) && R([myObject setValue: [OFNumber numberWithUnsignedShort: 70] forKey: @"unsignedShortValue"]) && R([myObject setValue: [OFNumber numberWithUnsignedInt: 80] forKey: @"unsignedIntValue"]) && R([myObject setValue: [OFNumber numberWithUnsignedLong: 90] forKey: @"unsignedLongValue"]) && R([myObject setValue: [OFNumber numberWithUnsignedLongLong: 100] forKey: @"unsignedLongLongValue"]) && R([myObject setValue: [OFNumber numberWithFloat: 110] forKey: @"floatValue"]) && R([myObject setValue: [OFNumber numberWithDouble: 120] forKey: @"doubleValue"]) && myObject.isBoolValue == 0 && myObject.charValue == 10 && myObject.shortValue == 20 && myObject.intValue == 30 && myObject.longValue == 40 && myObject.longLongValue == 50 && myObject.unsignedCharValue == 60 && myObject.unsignedShortValue == 70 && myObject.unsignedIntValue == 80 && myObject.unsignedLongValue == 90 && myObject.unsignedLongLongValue == 100 && myObject.floatValue == 110 && myObject.doubleValue == 120) EXPECT_EXCEPTION(@"Catch -[setValue:forKey:] with nil key for scalar", OFInvalidArgumentException, [myObject setValue: (id _Nonnull)nil forKey: @"intValue"]) TEST(@"-[valueForKeyPath:]", (myObject = [[[MyObject alloc] init] autorelease]) && (myObject.objectValue = [[[MyObject alloc] init] autorelease]) && R([myObject.objectValue setObjectValue: [[[MyObject alloc] init] autorelease]]) && R([[myObject.objectValue objectValue] setDoubleValue: 0.5]) && [[myObject valueForKeyPath: @"objectValue.objectValue.doubleValue"] doubleValue] == 0.5) TEST(@"[-setValue:forKeyPath:]", R([myObject setValue: [OFNumber numberWithDouble: 0.75] forKeyPath: @"objectValue.objectValue.doubleValue"]) && [[myObject.objectValue objectValue] doubleValue] == 0.75) objc_autoreleasePoolPop(pool); } @end |
Renamed and modified tests/PBKDF2Tests.m [1bccd3d759] to tests/OFPBKDF2Tests.m [9316c48e09].
1 | /* | < < | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFPBKDF2"; @implementation TestsAppDelegate (OFPBKDF2Tests) - (void)PBKDF2Tests { void *pool = objc_autoreleasePoolPush(); OFHMAC *HMAC = [OFHMAC HMACWithHashClass: [OFSHA1Hash class] allowsSwappableMemory: true]; unsigned char key[25]; /* Test vectors from RFC 6070 */ TEST(@"PBKDF2-SHA1, 1 iteration", R(OFPBKDF2((OFPBKDF2Parameters){ .HMAC = HMAC, .iterations = 1, .salt = (unsigned char *)"salt", .saltLength = 4, .password = "password", .passwordLength = 8, .key = key, .keyLength = 20, .allowsSwappableMemory = true })) && memcmp(key, "\x0C\x60\xC8\x0F\x96\x1F\x0E\x71\xF3\xA9\xB5" "\x24\xAF\x60\x12\x06\x2F\xE0\x37\xA6", 20) == 0) TEST(@"PBKDF2-SHA1, 2 iterations", R(OFPBKDF2((OFPBKDF2Parameters){ .HMAC = HMAC, .iterations = 2, .salt = (unsigned char *)"salt", .saltLength = 4, .password = "password", .passwordLength = 8, .key = key, .keyLength = 20, .allowsSwappableMemory = true })) && memcmp(key, "\xEA\x6C\x01\x4D\xC7\x2D\x6F\x8C\xCD\x1E\xD9" "\x2A\xCE\x1D\x41\xF0\xD8\xDE\x89\x57", 20) == 0) TEST(@"PBKDF2-SHA1, 4096 iterations", R(OFPBKDF2((OFPBKDF2Parameters){ .HMAC = HMAC, .iterations = 4096, .salt = (unsigned char *)"salt", .saltLength = 4, .password = "password", .passwordLength = 8, .key = key, .keyLength = 20, .allowsSwappableMemory = true })) && memcmp(key, "\x4B\x00\x79\x01\xB7\x65\x48\x9A\xBE\xAD\x49" "\xD9\x26\xF7\x21\xD0\x65\xA4\x29\xC1", 20) == 0) /* This test takes too long, even on a fast machine. */ #if 0 TEST(@"PBKDF2-SHA1, 16777216 iterations", R(OFPBKDF2((OFPBKDF2Parameters){ .HMAC = HMAC, .iterations = 16777216, .salt = (unsigned char *)"salt", .saltLength = 4, .password = "password", .passwordLength = 8, .key = key, .keyLength = 20, .allowsSwappableMemory = true })) && memcmp(key, "\xEE\xFE\x3D\x61\xCD\x4D\xA4\xE4\xE9\x94\x5B" "\x3D\x6B\xA2\x15\x8C\x26\x34\xE9\x84", 20) == 0) #endif TEST(@"PBKDF2-SHA1, 4096 iterations, key > 1 block", R(OFPBKDF2((OFPBKDF2Parameters){ .HMAC = HMAC, .iterations = 4096, .salt = (unsigned char *)"saltSALTsaltSALTsalt" "SALTsaltSALTsalt", .saltLength = 36, .password = "passwordPASSWORDpassword", .passwordLength = 24, .key = key, .keyLength = 25, .allowsSwappableMemory = true })) && memcmp(key, "\x3D\x2E\xEC\x4F\xE4\x1C\x84\x9B\x80\xC8\xD8\x36\x62" "\xC0\xE4\x4A\x8B\x29\x1A\x96\x4C\xF2\xF0\x70\x38", 25) == 0) TEST(@"PBKDF2-SHA1, 4096 iterations, key < 1 block", R(OFPBKDF2((OFPBKDF2Parameters){ .HMAC = HMAC, .iterations = 4096, .salt = (unsigned char *)"sa\0lt", .saltLength = 5, .password = "pass\0word", .passwordLength = 9, .key = key, |
︙ | ︙ |
Modified tests/OFPluginTests.m from [cf1db3ca7b] to [bb55705657].
1 | /* | < < | | | | > > > | > > | | > > > > > | > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" #import "plugin/TestPlugin.h" #ifndef OF_IOS static OFString *const pluginName = @"plugin/TestPlugin"; #else static OFString *const pluginName = @"PlugIns/TestPlugin"; #endif static OFString *const module = @"OFPlugin"; @implementation TestsAppDelegate (OFPluginTests) - (void)pluginTests { void *pool = objc_autoreleasePoolPush(); OFString *path; OFPlugin *plugin; Class (*class)(void); TestPlugin *test; TEST(@"+[pathForName:]", (path = [OFPlugin pathForName: pluginName])) TEST(@"+[pluginWithPath:]", (plugin = [OFPlugin pluginWithPath: path])) TEST(@"-[addressForSymbol:]", (class = (Class (*)(void))(uintptr_t) [plugin addressForSymbol: @"class"])) test = [[class() alloc] init]; @try { TEST(@"TestPlugin's -[test:]", [test test: 1234] == 2468) } @finally { [test release]; } objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFPropertyListTests.m from [f260520db3] to [6b258c8840].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | @"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \ @"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " \ @"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" \ @"<plist version=\"1.0\">\n" \ x @"\n" \ @"</plist>" | | | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | @"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \ @"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " \ @"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" \ @"<plist version=\"1.0\">\n" \ x @"\n" \ @"</plist>" static OFString *const module = @"OFPropertyList"; static OFString *const PLIST1 = PLIST(@"<string>Hello</string>"); static OFString *const PLIST2 = PLIST( @"<array>" @" <string>Hello</string>" @" <data>V29ybGQh</data>" @" <date>2018-03-14T12:34:56Z</date>" @" <true/>" @" <false/>" @" <real>12.25</real>" @" <integer>-10</integer>" @"</array>"); static OFString *const PLIST3 = PLIST( @"<dict>" @" <key>array</key>" @" <array>" @" <string>Hello</string>" @" <data>V29ybGQh</data>" @" <date>2018-03-14T12:34:56Z</date>" @" <true/>" |
︙ | ︙ | |||
57 58 59 60 61 62 63 | @implementation TestsAppDelegate (OFPLISTParser) - (void)propertyListTests { void *pool = objc_autoreleasePoolPush(); OFArray *array = [OFArray arrayWithObjects: @"Hello", | | < | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | @implementation TestsAppDelegate (OFPLISTParser) - (void)propertyListTests { void *pool = objc_autoreleasePoolPush(); OFArray *array = [OFArray arrayWithObjects: @"Hello", [OFData dataWithItems: "World!" count: 6], [OFDate dateWithTimeIntervalSince1970: 1521030896], [OFNumber numberWithBool: true], [OFNumber numberWithBool: false], [OFNumber numberWithFloat: 12.25f], [OFNumber numberWithInt: -10], nil]; |
︙ | ︙ |
Modified tests/OFRIPEMD160HashTests.m from [e2102eafad] to [4b80756e64].
1 | /* | < < | | | | | < | < | | | | < | < | > | > > | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFRIPEMD160Hash"; const uint8_t testFileRIPEMD160[20] = "\x46\x02\x97\xF5\x85\xDF\xB9\x21\x00\xC8\xF9\x87\xC6\xEC\x84\x0D\xCE" "\xE6\x08\x8B"; @implementation TestsAppDelegate (OFRIPEMD160HashTests) - (void)RIPEMD160HashTests { void *pool = objc_autoreleasePoolPush(); OFRIPEMD160Hash *RIPEMD160, *RIPEMD160Copy; OFFile *file = [OFFile fileWithPath: @"testfile.bin" mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (RIPEMD160 = [OFRIPEMD160Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { char buffer[64]; size_t length = [file readIntoBuffer: buffer length: 64]; [RIPEMD160 updateWithBuffer: buffer length: length]; } [file close]; TEST(@"-[copy]", (RIPEMD160Copy = [[RIPEMD160 copy] autorelease])) TEST(@"-[calculate]", R([RIPEMD160 calculate]) && R([RIPEMD160Copy calculate])) TEST(@"-[digest]", memcmp(RIPEMD160.digest, testFileRIPEMD160, 20) == 0 && memcmp(RIPEMD160Copy.digest, testFileRIPEMD160, 20) == 0) EXPECT_EXCEPTION(@"Detect invalid call of " @"-[updateWithBuffer:length]", OFHashAlreadyCalculatedException, [RIPEMD160 updateWithBuffer: "" length: 1]) objc_autoreleasePoolPop(pool); } @end |
Deleted tests/OFSCTPSocketTests.m version [810fa289fa].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Modified tests/OFSHA1HashTests.m from [ccf0765a92] to [f5847018f6].
1 | /* | < < | | | | | < | | | | | < | < | | > > | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFSHA1Hash"; const uint8_t testFileSHA1[20] = "\xC9\x9A\xB8\x7E\x1E\xC8\xEC\x65\xD5\xEB\xE4\x2E\x0D\xA6\x80\x96\xF5" "\x94\xE7\x17"; @implementation TestsAppDelegate (SHA1HashTests) - (void)SHA1HashTests { void *pool = objc_autoreleasePoolPush(); OFSHA1Hash *SHA1, *SHA1Copy; OFFile *file = [OFFile fileWithPath: @"testfile.bin" mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (SHA1 = [OFSHA1Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { char buffer[64]; size_t length = [file readIntoBuffer: buffer length: 64]; [SHA1 updateWithBuffer: buffer length: length]; } [file close]; TEST(@"-[copy]", (SHA1Copy = [[SHA1 copy] autorelease])) TEST(@"-[calculate]", R([SHA1 calculate]) && R([SHA1Copy calculate])) TEST(@"-[digest]", memcmp(SHA1.digest, testFileSHA1, 20) == 0 && memcmp(SHA1Copy.digest, testFileSHA1, 20) == 0) EXPECT_EXCEPTION(@"Detect invalid call of " @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException, [SHA1 updateWithBuffer: "" length: 1]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFSHA224HashTests.m from [be6b7ce0e2] to [f0d335ef4f].
1 | /* | < < | | | | | < | | | | | < | < | > | > > | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFSHA224Hash"; const uint8_t testFileSHA224[28] = "\x27\x69\xD8\x04\x2D\x0F\xCA\x84\x6C\xF1\x62\x44\xBA\x0C\xBD\x46\x64" "\x5F\x4F\x20\x02\x4D\x15\xED\x1C\x61\x1F\xF7"; @implementation TestsAppDelegate (SHA224HashTests) - (void)SHA224HashTests { void *pool = objc_autoreleasePoolPush(); OFSHA224Hash *SHA224, *SHA224Copy; OFFile *file = [OFFile fileWithPath: @"testfile.bin" mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (SHA224 = [OFSHA224Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { char buffer[64]; size_t length = [file readIntoBuffer: buffer length: 64]; [SHA224 updateWithBuffer: buffer length: length]; } [file close]; TEST(@"-[copy]", (SHA224Copy = [[SHA224 copy] autorelease])) TEST(@"-[calculate]", R([SHA224 calculate]) && R([SHA224Copy calculate])) TEST(@"-[digest]", memcmp(SHA224.digest, testFileSHA224, 28) == 0 && memcmp(SHA224Copy.digest, testFileSHA224, 28) == 0) EXPECT_EXCEPTION(@"Detect invalid call of " @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException, [SHA224 updateWithBuffer: "" length: 1]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFSHA256HashTests.m from [207defcf79] to [2075144684].
1 | /* | < < | | | | | < | | | | | < | < | > | > > | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFSHA256Hash"; const uint8_t testFileSHA256[32] = "\x1A\x02\xD6\x46\xF5\xA6\xBA\xAA\xFF\x7F\xD5\x87\xBA\xC3\xF6\xC6\xB5" "\x67\x93\x8F\x0F\x44\x90\xB8\xF5\x35\x89\xF0\x5A\x23\x7F\x69"; @implementation TestsAppDelegate (SHA256HashTests) - (void)SHA256HashTests { void *pool = objc_autoreleasePoolPush(); OFSHA256Hash *SHA256, *SHA256Copy; OFFile *file = [OFFile fileWithPath: @"testfile.bin" mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (SHA256 = [OFSHA256Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { char buffer[64]; size_t length = [file readIntoBuffer: buffer length: 64]; [SHA256 updateWithBuffer: buffer length: length]; } [file close]; TEST(@"-[copy]", (SHA256Copy = [[SHA256 copy] autorelease])) TEST(@"-[calculate]", R([SHA256 calculate]) && R([SHA256Copy calculate])) TEST(@"-[digest]", memcmp(SHA256.digest, testFileSHA256, 32) == 0 && memcmp(SHA256Copy.digest, testFileSHA256, 32) == 0) EXPECT_EXCEPTION(@"Detect invalid call of " @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException, [SHA256 updateWithBuffer: "" length: 1]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFSHA384HashTests.m from [3b765b947e] to [9815671ea1].
1 | /* | < < | | | | | < | | | | | < | < | > | > > | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFSHA384Hash"; const uint8_t testFileSHA384[48] = "\x7E\xDE\x62\xE2\x10\xA5\x1E\x18\x8A\x11\x7F\x78\xD7\xC7\x55\xB6\x43" "\x94\x1B\xD2\x78\x5C\xCF\xF3\x8A\xB8\x98\x22\xC7\x0E\xFE\xF1\xEC\x53" "\xE9\x1A\xB3\x51\x70\x8C\x1F\x3F\x56\x12\x44\x01\x91\x54"; @implementation TestsAppDelegate (SHA384HashTests) - (void)SHA384HashTests { void *pool = objc_autoreleasePoolPush(); OFSHA384Hash *SHA384, *SHA384Copy; OFFile *file = [OFFile fileWithPath: @"testfile.bin" mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (SHA384 = [OFSHA384Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { char buffer[128]; size_t length = [file readIntoBuffer: buffer length: 128]; [SHA384 updateWithBuffer: buffer length: length]; } [file close]; TEST(@"-[copy]", (SHA384Copy = [[SHA384 copy] autorelease])) TEST(@"-[calculate]", R([SHA384 calculate]) && R([SHA384Copy calculate])) TEST(@"-[digest]", memcmp(SHA384.digest, testFileSHA384, 48) == 0 && memcmp(SHA384Copy.digest, testFileSHA384, 48) == 0) EXPECT_EXCEPTION(@"Detect invalid call of " @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException, [SHA384 updateWithBuffer: "" length: 1]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFSHA512HashTests.m from [9088f78182] to [8ea1d53446].
1 | /* | < < | | | | | < | | | | | < | < | > | > > | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFSHA512Hash"; const uint8_t testFileSHA512[64] = "\x8F\x36\x6E\x3C\x19\x4B\xBB\xC7\x82\xAA\xCD\x7D\x55\xA2\xD3\x29\x29" "\x97\x6A\x3F\xEB\x9B\xB2\xCB\x75\xC9\xEC\xC8\x10\x07\xD6\x07\x31\x4A" "\xB1\x30\x97\x82\x58\xA5\x1F\x71\x42\xE6\x56\x07\x99\x57\xB2\xB8\x3B" "\xA1\x8A\x41\x64\x33\x69\x21\x8C\x2A\x44\x6D\xF2\xA0"; @implementation TestsAppDelegate (SHA512HashTests) - (void)SHA512HashTests { void *pool = objc_autoreleasePoolPush(); OFSHA512Hash *SHA512, *SHA512Copy; OFFile *file = [OFFile fileWithPath: @"testfile.bin" mode: @"r"]; TEST(@"+[hashWithAllowsSwappableMemory:]", (SHA512 = [OFSHA512Hash hashWithAllowsSwappableMemory: true])) while (!file.atEndOfStream) { char buffer[128]; size_t length = [file readIntoBuffer: buffer length: 128]; [SHA512 updateWithBuffer: buffer length: length]; } [file close]; TEST(@"-[copy]", (SHA512Copy = [[SHA512 copy] autorelease])) TEST(@"-[calculate]", R([SHA512 calculate]) && R([SHA512Copy calculate])) TEST(@"-[digest]", memcmp(SHA512.digest, testFileSHA512, 64) == 0 && memcmp(SHA512Copy.digest, testFileSHA512, 64) == 0) EXPECT_EXCEPTION(@"Detect invalid call of " @"-[updateWithBuffer:length:]", OFHashAlreadyCalculatedException, [SHA512 updateWithBuffer: "" length: 1]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFSPXSocketTests.m from [e438c57a59] to [3e5f030bd3].
1 | /* | < < | | | | | | | | | | | | | | | | | | | | < < | < | < | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFSPXSocket"; @interface SPXSocketDelegate: OFObject <OFSPXSocketDelegate> { @public OFSequencedPacketSocket *_expectedServerSocket; OFSPXSocket *_expectedClientSocket; unsigned char _expectedNode[IPX_NODE_LEN]; uint32_t _expectedNetwork; uint16_t _expectedPort; bool _accepted; bool _connected; } @end @implementation SPXSocketDelegate - (bool)socket: (OFSequencedPacketSocket *)sock didAcceptSocket: (OFSequencedPacketSocket *)accepted exception: (id)exception { OFEnsure(!_accepted); _accepted = (sock == _expectedServerSocket && accepted != nil && exception == nil); if (_accepted && _connected) [[OFRunLoop mainRunLoop] stop]; return false; } - (void)socket: (OFSPXSocket *)sock didConnectToNode: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port exception: (id)exception { OFEnsure(!_connected); _connected = (sock == _expectedClientSocket && memcmp(node, _expectedNode, IPX_NODE_LEN) == 0 && network == _expectedNetwork && port == _expectedPort && exception == nil); if (_accepted && _connected) [[OFRunLoop mainRunLoop] stop]; } @end @implementation TestsAppDelegate (OFSPXSocketTests) - (void)SPXSocketTests { void *pool = objc_autoreleasePoolPush(); OFSPXSocket *sockClient, *sockServer = nil, *sockAccepted; OFSocketAddress address1; const OFSocketAddress *address2; unsigned char node[IPX_NODE_LEN], node2[IPX_NODE_LEN]; uint32_t network; uint16_t port; char buffer[5]; SPXSocketDelegate *delegate; TEST(@"+[socket]", (sockClient = [OFSPXSocket socket]) && (sockServer = [OFSPXSocket socket])) @try { TEST(@"-[bindToPort:]", R(address1 = [sockServer bindToPort: 0])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFSPXSocket] -[bindToPort:]: " @"IPX unsupported, skipping tests"]; break; case ESOCKTNOSUPPORT: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFSPXSocket] -[bindToPort:]: " @"SPX unsupported, skipping tests"]; break; case EADDRNOTAVAIL: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFSPXSocket] -[bindToPort:]: " @"IPX not configured, skipping tests"]; break; default: @throw e; } objc_autoreleasePoolPop(pool); return; } OFSocketAddressIPXNode(&address1, node); network = OFSocketAddressIPXNetwork(&address1); port = OFSocketAddressPort(&address1); TEST(@"-[listen]", R([sockServer listen])) TEST(@"-[connectToNode:network:port:]", R([sockClient connectToNode: node network: network port: port])) TEST(@"-[accept]", (sockAccepted = [sockServer accept])) TEST(@"-[sendBuffer:length:]", R([sockAccepted sendBuffer: "Hello" length: 5])) TEST(@"-[receiveIntoBuffer:length:]", [sockClient receiveIntoBuffer: buffer length: 5] == 5 && memcmp(buffer, "Hello", 5) == 0) TEST(@"-[remoteAddress]", (address2 = sockAccepted.remoteAddress) && R(OFSocketAddressIPXNode(address2, node2)) && memcmp(node, node2, IPX_NODE_LEN) == 0 && OFSocketAddressIPXNetwork(address2) == network) delegate = [[[SPXSocketDelegate alloc] init] autorelease]; sockServer = [OFSPXSocket socket]; delegate->_expectedServerSocket = sockServer; sockServer.delegate = delegate; sockClient = [OFSPXSocket socket]; delegate->_expectedClientSocket = sockClient; sockClient.delegate = delegate; address1 = [sockServer bindToPort: 0]; [sockServer listen]; [sockServer asyncAccept]; OFSocketAddressIPXNode(&address1, node); memcpy(delegate->_expectedNode, node, IPX_NODE_LEN); delegate->_expectedNetwork = network = OFSocketAddressIPXNetwork(&address1); delegate->_expectedPort = port = OFSocketAddressPort(&address1); @try { [sockClient asyncConnectToNode: node network: network port: port]; [[OFRunLoop mainRunLoop] runUntilDate: [OFDate dateWithTimeIntervalSinceNow: 2]]; TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]", delegate->_accepted && delegate->_connected) } @catch (OFObserveFailedException *e) { switch (e.errNo) { case ENOTSOCK: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFSPXSocket] -[asyncAccept] & " @"-[asyncConnectToNode:network:port:]: select() " @"not supported for SPX, skipping test"]; break; default: @throw e; } } objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFSPXStreamSocketTests.m from [4e87ecb1d0] to [30183cbd9e].
1 | /* | < < | | | | | | | | | | | | | | | | | | | | < < | < | < | < | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFSPXStreamSocket"; @interface SPXStreamSocketDelegate: OFObject <OFSPXStreamSocketDelegate> { @public OFStreamSocket *_expectedServerSocket; OFSPXStreamSocket *_expectedClientSocket; unsigned char _expectedNode[IPX_NODE_LEN]; uint32_t _expectedNetwork; uint16_t _expectedPort; bool _accepted; bool _connected; } @end @implementation SPXStreamSocketDelegate - (bool)socket: (OFStreamSocket *)sock didAcceptSocket: (OFStreamSocket *)accepted exception: (id)exception { OFEnsure(!_accepted); _accepted = (sock == _expectedServerSocket && accepted != nil && exception == nil); if (_accepted && _connected) [[OFRunLoop mainRunLoop] stop]; return false; } - (void)socket: (OFSPXStreamSocket *)sock didConnectToNode: (unsigned char [IPX_NODE_LEN])node network: (uint32_t)network port: (uint16_t)port exception: (id)exception { OFEnsure(!_connected); _connected = (sock == _expectedClientSocket && memcmp(node, _expectedNode, IPX_NODE_LEN) == 0 && network == _expectedNetwork && port == _expectedPort && exception == nil); if (_accepted && _connected) [[OFRunLoop mainRunLoop] stop]; } @end @implementation TestsAppDelegate (OFSPXStreamSocketTests) - (void)SPXStreamSocketTests { void *pool = objc_autoreleasePoolPush(); OFSPXStreamSocket *sockClient, *sockServer = nil, *sockAccepted; OFSocketAddress address1; const OFSocketAddress *address2; unsigned char node[IPX_NODE_LEN], node2[IPX_NODE_LEN]; uint32_t network; uint16_t port; char buffer[5]; SPXStreamSocketDelegate *delegate; TEST(@"+[socket]", (sockClient = [OFSPXStreamSocket socket]) && (sockServer = [OFSPXStreamSocket socket])) @try { TEST(@"-[bindToPort:]", R(address1 = [sockServer bindToPort: 0])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFSPXStreamSocket] -[bindToPort:]: " @"IPX unsupported, skipping tests"]; break; case ESOCKTNOSUPPORT: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFSPXStreamSocket] -[bindToPort:]: " @"SPX unsupported, skipping tests"]; break; case EADDRNOTAVAIL: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFSPXStreamSocket] -[bindToPort:]: " @"IPX not configured, skipping tests"]; break; default: @throw e; } objc_autoreleasePoolPop(pool); return; } OFSocketAddressIPXNode(&address1, node); network = OFSocketAddressIPXNetwork(&address1); port = OFSocketAddressPort(&address1); TEST(@"-[listen]", R([sockServer listen])) TEST(@"-[connectToNode:network:port:]", R([sockClient connectToNode: node network: network port: port])) TEST(@"-[accept]", (sockAccepted = [sockServer accept])) /* Test reassembly (this would not work with OFSPXSocket) */ TEST(@"-[writeBuffer:length:]", R([sockAccepted writeBuffer: "Hello" length: 5])) TEST(@"-[readIntoBuffer:length:]", [sockClient readIntoBuffer: buffer length: 2] == 2 && memcmp(buffer, "He", 2) == 0 && [sockClient readIntoBuffer: buffer length: 3] == 3 && memcmp(buffer, "llo", 3) == 0) TEST(@"-[remoteAddress]", (address2 = sockAccepted.remoteAddress) && R(OFSocketAddressIPXNode(address2, node2)) && memcmp(node, node2, IPX_NODE_LEN) == 0 && OFSocketAddressIPXNetwork(address2) == network) delegate = [[[SPXStreamSocketDelegate alloc] init] autorelease]; sockServer = [OFSPXStreamSocket socket]; delegate->_expectedServerSocket = sockServer; sockServer.delegate = delegate; sockClient = [OFSPXStreamSocket socket]; delegate->_expectedClientSocket = sockClient; sockClient.delegate = delegate; address1 = [sockServer bindToPort: 0]; [sockServer listen]; [sockServer asyncAccept]; OFSocketAddressIPXNode(&address1, node); memcpy(delegate->_expectedNode, node, IPX_NODE_LEN); delegate->_expectedNetwork = network = OFSocketAddressIPXNetwork(&address1); delegate->_expectedPort = port = OFSocketAddressPort(&address1); @try { [sockClient asyncConnectToNode: node network: network port: port]; [[OFRunLoop mainRunLoop] runUntilDate: [OFDate dateWithTimeIntervalSinceNow: 2]]; TEST(@"-[asyncAccept] & -[asyncConnectToNode:network:port:]", delegate->_accepted && delegate->_connected) } @catch (OFObserveFailedException *e) { switch (e.errNo) { case ENOTSOCK: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFSPXStreamSocket] -[asyncAccept] & " @"-[asyncConnectToNode:network:port:]: select() " @"not supported for SPX, skipping test"]; break; default: @throw e; } } objc_autoreleasePoolPop(pool); } @end |
Renamed and modified tests/ScryptTests.m [b2b1c50b4e] to tests/OFScryptTests.m [b11c7bebe9].
1 | /* | < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFScrypt"; /* Test vectors form RFC 7914 */ static const unsigned char salsa20Input[64] = { 0x7E, 0x87, 0x9A, 0x21, 0x4F, 0x3E, 0xC9, 0x86, 0x7C, 0xA9, 0x40, 0xE6, 0x41, 0x71, 0x8F, 0x26, 0xBA, 0xEE, 0x55, 0x5B, 0x8C, 0x61, 0xC1, 0xB5, 0x0D, 0xF8, 0x46, 0x11, 0x6D, 0xCD, 0x3B, 0x1D, 0xEE, 0x24, 0xF3, 0x19, 0xDF, 0x9B, 0x3D, 0x85, 0x14, 0x12, 0x1E, 0x4B, 0x5A, 0xC5, 0xAA, 0x32, 0x76, 0x02, 0x1D, 0x29, 0x09, 0xC7, 0x48, 0x29, 0xED, 0xEB, 0xC6, 0x8D, |
︙ | ︙ | |||
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | 0xFD, 0xBA, 0xBE, 0x1C, 0x9D, 0x34, 0x72, 0x00, 0x78, 0x56, 0xE7, 0x19, 0x0D, 0x01, 0xE9, 0xFE, 0x7C, 0x6A, 0xD7, 0xCB, 0xC8, 0x23, 0x78, 0x30, 0xE7, 0x73, 0x76, 0x63, 0x4B, 0x37, 0x31, 0x62, 0x2E, 0xAF, 0x30, 0xD9, 0x2E, 0x22, 0xA3, 0x88, 0x6F, 0xF1, 0x09, 0x27, 0x9D, 0x98, 0x30, 0xDA, 0xC7, 0x27, 0xAF, 0xB9, 0x4A, 0x83, 0xEE, 0x6D, 0x83, 0x60, 0xCB, 0xDF, 0xA2, 0xCC, 0x06, 0x40 }; static const unsigned char testVector3[64] = { 0x70, 0x23, 0xBD, 0xCB, 0x3A, 0xFD, 0x73, 0x48, 0x46, 0x1C, 0x06, 0xCD, 0x81, 0xFD, 0x38, 0xEB, 0xFD, 0xA8, 0xFB, 0xBA, 0x90, 0x4F, 0x8E, 0x3E, 0xA9, 0xB5, 0x43, 0xF6, 0x54, 0x5D, 0xA1, 0xF2, 0xD5, 0x43, 0x29, 0x55, 0x61, 0x3F, 0x0F, 0xCF, 0x62, 0xD4, 0x97, 0x05, 0x24, 0x2A, 0x9A, 0xF9, 0xE6, 0x1E, 0x85, 0xDC, 0x0D, 0x65, 0x1E, 0x40, 0xDF, 0xCF, 0x01, 0x7B, 0x45, 0x57, 0x58, 0x87 }; /* The forth test vector is too expensive to include it in the tests. */ #if 0 static const unsigned char testVector4[64] = { 0x21, 0x01, 0xCB, 0x9B, 0x6A, 0x51, 0x1A, 0xAE, 0xAD, 0xDB, 0xBE, 0x09, 0xCF, 0x70, 0xF8, 0x81, 0xEC, 0x56, 0x8D, 0x57, 0x4A, 0x2F, 0xFD, 0x4D, 0xAB, 0xE5, 0xEE, 0x98, 0x20, 0xAD, 0xAA, 0x47, 0x8E, 0x56, 0xFD, 0x8F, 0x4B, 0xA5, 0xD0, 0x9F, 0xFA, 0x1C, 0x6D, 0x92, 0x7C, 0x40, 0xF4, 0xC3, 0x37, 0x30, 0x40, 0x49, 0xE8, 0xA9, 0x52, 0xFB, 0xCB, 0xF4, 0x5C, 0x6F, 0xA7, 0x7A, 0x41, 0xA4 }; #endif | > > > | | | | | | > > | > | | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | 0xFD, 0xBA, 0xBE, 0x1C, 0x9D, 0x34, 0x72, 0x00, 0x78, 0x56, 0xE7, 0x19, 0x0D, 0x01, 0xE9, 0xFE, 0x7C, 0x6A, 0xD7, 0xCB, 0xC8, 0x23, 0x78, 0x30, 0xE7, 0x73, 0x76, 0x63, 0x4B, 0x37, 0x31, 0x62, 0x2E, 0xAF, 0x30, 0xD9, 0x2E, 0x22, 0xA3, 0x88, 0x6F, 0xF1, 0x09, 0x27, 0x9D, 0x98, 0x30, 0xDA, 0xC7, 0x27, 0xAF, 0xB9, 0x4A, 0x83, 0xEE, 0x6D, 0x83, 0x60, 0xCB, 0xDF, 0xA2, 0xCC, 0x06, 0x40 }; /* The third test vector is too expensive for m68k. */ #ifndef OF_M68K static const unsigned char testVector3[64] = { 0x70, 0x23, 0xBD, 0xCB, 0x3A, 0xFD, 0x73, 0x48, 0x46, 0x1C, 0x06, 0xCD, 0x81, 0xFD, 0x38, 0xEB, 0xFD, 0xA8, 0xFB, 0xBA, 0x90, 0x4F, 0x8E, 0x3E, 0xA9, 0xB5, 0x43, 0xF6, 0x54, 0x5D, 0xA1, 0xF2, 0xD5, 0x43, 0x29, 0x55, 0x61, 0x3F, 0x0F, 0xCF, 0x62, 0xD4, 0x97, 0x05, 0x24, 0x2A, 0x9A, 0xF9, 0xE6, 0x1E, 0x85, 0xDC, 0x0D, 0x65, 0x1E, 0x40, 0xDF, 0xCF, 0x01, 0x7B, 0x45, 0x57, 0x58, 0x87 }; #endif /* The forth test vector is too expensive to include it in the tests. */ #if 0 static const unsigned char testVector4[64] = { 0x21, 0x01, 0xCB, 0x9B, 0x6A, 0x51, 0x1A, 0xAE, 0xAD, 0xDB, 0xBE, 0x09, 0xCF, 0x70, 0xF8, 0x81, 0xEC, 0x56, 0x8D, 0x57, 0x4A, 0x2F, 0xFD, 0x4D, 0xAB, 0xE5, 0xEE, 0x98, 0x20, 0xAD, 0xAA, 0x47, 0x8E, 0x56, 0xFD, 0x8F, 0x4B, 0xA5, 0xD0, 0x9F, 0xFA, 0x1C, 0x6D, 0x92, 0x7C, 0x40, 0xF4, 0xC3, 0x37, 0x30, 0x40, 0x49, 0xE8, 0xA9, 0x52, 0xFB, 0xCB, 0xF4, 0x5C, 0x6F, 0xA7, 0x7A, 0x41, 0xA4 }; #endif @implementation TestsAppDelegate (OFScryptTests) - (void)scryptTests { void *pool = objc_autoreleasePoolPush(); uint32_t salsa20Buffer[16]; uint32_t blockMixBuffer[32]; uint32_t ROMixBuffer[32], ROMixTmp[17 * 32]; unsigned char output[64]; TEST(@"Salsa20/8 Core", R(memcpy(salsa20Buffer, salsa20Input, 64)) && R(OFSalsa20_8Core(salsa20Buffer)) && memcmp(salsa20Buffer, salsa20Output, 64) == 0) TEST(@"Block mix", R(OFScryptBlockMix(blockMixBuffer, blockMixInput.u32, 1)) && memcmp(blockMixBuffer, blockMixOutput, 128) == 0) TEST(@"ROMix", R(memcpy(ROMixBuffer, ROMixInput, 128)) && R(OFScryptROMix(ROMixBuffer, 1, 16, ROMixTmp)) && memcmp(ROMixBuffer, ROMixOutput, 128) == 0) TEST(@"scrypt test vector #1", R(OFScrypt((OFScryptParameters){ .blockSize = 1, .costFactor = 16, .parallelization = 1, .salt = (unsigned char *)"", .saltLength = 0, .password = "", .passwordLength = 0, .key = output, .keyLength = 64, .allowsSwappableMemory = true })) && memcmp(output, testVector1, 64) == 0) TEST(@"scrypt test vector #2", R(OFScrypt((OFScryptParameters){ .blockSize = 8, .costFactor = 1024, .parallelization = 16, .salt = (unsigned char *)"NaCl", .saltLength = 4, .password = "password", .passwordLength = 8, .key = output, .keyLength = 64, .allowsSwappableMemory = true })) && memcmp(output, testVector2, 64) == 0) /* The third test vector is too expensive for m68k. */ #ifndef OF_M68K TEST(@"scrypt test vector #3", R(OFScrypt((OFScryptParameters){ .blockSize = 8, .costFactor = 16384, .parallelization = 1, .salt = (unsigned char *)"SodiumChloride", .saltLength = 14, .password = "pleaseletmein", .passwordLength = 13, .key = output, .keyLength = 64, .allowsSwappableMemory = true })) && memcmp(output, testVector3, 64) == 0) #endif /* The forth test vector is too expensive to include it in the tests. */ #if 0 TEST(@"scrypt test vector #4", R(OFScrypt((OFScryptParameters){ .blockSize = 8, .costFactor = 1048576, .parallelization = 1, .salt = (unsigned char *)"SodiumChloride", .saltLength = 14, .password = "pleaseletmein", .passwordLength = 13, |
︙ | ︙ |
Modified tests/OFSerializationTests.m from [50a2e2daf3] to [5fdb00c13b].
1 | /* | < < | | | | | | > | | | | | | < | < | | | | > | | | < | | > > > | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFSerialization"; @implementation TestsAppDelegate (OFSerializationTests) - (void)serializationTests { void *pool = objc_autoreleasePoolPush(); OFMutableDictionary *dict = [OFMutableDictionary dictionary]; OFMutableArray *array = [OFMutableArray array]; OFList *list = [OFList list]; OFData *data; OFString *string; OFUUID *UUID; [array addObject: @"Qu\"xbar\ntest"]; [array addObject: [OFNumber numberWithInt: 1234]]; [array addObject: [OFNumber numberWithDouble: 1234.5678]]; [array addObject: [OFMutableString stringWithString: @"asd"]]; [array addObject: [OFDate dateWithTimeIntervalSince1970: 1234.5678]]; [dict setObject: @"Hello" forKey: array]; [dict setObject: @"B\"la" forKey: @"Blub"]; [list appendObject: @"Hello"]; [list appendObject: @"Wo\rld!\nHow are you?"]; [list appendObject: [OFURL URLWithString: @"https://objfw.nil.im/"]]; [list appendObject: [OFXMLElement elementWithXMLString: @"<x><y/><![CDATA[<]]></x>"]]; [list appendObject: [OFSet setWithObjects: @"foo", @"foo", @"bar", nil]]; [list appendObject: [OFCountedSet setWithObjects: @"foo", @"foo", @"bar", nil]]; [dict setObject: @"list" forKey: list]; data = [OFData dataWithItems: "0123456789:;<ABCDEFGHJIKLMNOPQRSTUVWXYZ" count: 39]; [dict setObject: @"data" forKey: data]; UUID = [OFUUID UUIDWithUUIDString: @"01234567-89AB-CDEF-FEDC-BA9876543210"]; [dict setObject: @"uuid" forKey: UUID]; TEST(@"-[stringBySerializing]", (string = dict.stringBySerializing) && [string isEqual: [OFString stringWithContentsOfFile: @"serialization.xml"]]) TEST(@"-[objectByDeserializing]", [string.objectByDeserializing isEqual: dict]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFSetTests.m from [1aa6d32b7b] to [d6c98b6473].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
19 20 21 22 23 24 25 | #import "TestsAppDelegate.h" #import "OFSet.h" #import "OFMapTableSet.h" #import "OFMutableMapTableSet.h" | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #import "TestsAppDelegate.h" #import "OFSet.h" #import "OFMapTableSet.h" #import "OFMutableMapTableSet.h" static OFString *module; @interface SimpleSet: OFSet { OFMutableSet *_set; } @end |
︙ | ︙ | |||
77 78 79 80 81 82 83 | [self release]; @throw e; } return self; } | | < | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | [self release]; @throw e; } return self; } - (instancetype)initWithObject: (id)firstObject arguments: (va_list)arguments { self = [super init]; @try { _set = [[OFMutableSet alloc] initWithObject: firstObject arguments: arguments]; } @catch (id e) { |
︙ | ︙ | |||
143 144 145 146 147 148 149 | [_set removeObject: object]; if (existed) _mutations++; } | | | < | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | [_set removeObject: object]; if (existed) _mutations++; } - (int)countByEnumeratingWithState: (OFFastEnumerationState *)state objects: (id *)objects count: (int)count { int ret = [_set countByEnumeratingWithState: state objects: objects count: count]; state->mutationsPtr = &_mutations; return ret; } @end @implementation TestsAppDelegate (OFSetTests) - (void)setTestsWithClass: (Class)setClass mutableClass: (Class)mutableSetClass { void *pool = objc_autoreleasePoolPush(); OFSet *set1, *set2; OFMutableSet *mutableSet; bool ok; size_t i; |
︙ | ︙ |
Renamed and modified tests/SocketTests.m [1f29b20927] to tests/OFSocketTests.m [3d043537f3].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
50 51 52 53 54 55 56 | a.sockaddr.in6.sin6_addr.s6_addr[10] = a5 >> 8; \ a.sockaddr.in6.sin6_addr.s6_addr[11] = a5 & 0xFF; \ a.sockaddr.in6.sin6_addr.s6_addr[12] = a6 >> 8; \ a.sockaddr.in6.sin6_addr.s6_addr[13] = a6 & 0xFF; \ a.sockaddr.in6.sin6_addr.s6_addr[14] = a7 >> 8; \ a.sockaddr.in6.sin6_addr.s6_addr[15] = a7 & 0xFF; | | | | < | | | | < | | < | | < | | < | | < | | < | > > | < | | | | | | | | | | | < | | < | | < | | < | | < | | < | | < | | < | | < | | > | | | < | < | < | | < | | < | | < | | < | | < < | < | | < | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | a.sockaddr.in6.sin6_addr.s6_addr[10] = a5 >> 8; \ a.sockaddr.in6.sin6_addr.s6_addr[11] = a5 & 0xFF; \ a.sockaddr.in6.sin6_addr.s6_addr[12] = a6 >> 8; \ a.sockaddr.in6.sin6_addr.s6_addr[13] = a6 & 0xFF; \ a.sockaddr.in6.sin6_addr.s6_addr[14] = a7 >> 8; \ a.sockaddr.in6.sin6_addr.s6_addr[15] = a7 & 0xFF; static OFString *const module = @"OFSocket"; @implementation TestsAppDelegate (OFSocketTests) - (void)socketTests { void *pool = objc_autoreleasePoolPush(); OFSocketAddress addr; TEST(@"Parsing an IPv4", R(addr = OFSocketAddressParseIP(@"127.0.0.1", 1234)) && OFFromBigEndian32(addr.sockaddr.in.sin_addr.s_addr) == 0x7F000001 && OFFromBigEndian16(addr.sockaddr.in.sin_port) == 1234) EXPECT_EXCEPTION(@"Refusing invalid IPv4 #1", OFInvalidFormatException, OFSocketAddressParseIP(@"127.0.0.0.1", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv4 #2", OFInvalidFormatException, OFSocketAddressParseIP(@"127.0.0.256", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv4 #3", OFInvalidFormatException, OFSocketAddressParseIP(@"127.0.0. 1", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv4 #4", OFInvalidFormatException, OFSocketAddressParseIP(@" 127.0.0.1", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv4 #5", OFInvalidFormatException, OFSocketAddressParseIP(@"127.0.a.1", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv4 #6", OFInvalidFormatException, OFSocketAddressParseIP(@"127.0..1", 1234)) TEST(@"Port of an IPv4 address", OFSocketAddressPort(&addr) == 1234) TEST(@"Converting an IPv4 to a string", [OFSocketAddressString(&addr) isEqual: @"127.0.0.1"]) TEST(@"Parsing an IPv6 #1", R(addr = OFSocketAddressParseIP( @"1122:3344:5566:7788:99aa:bbCc:ddee:ff00", 1234)) && COMPARE_V6(addr, 0x1122, 0x3344, 0x5566, 0x7788, 0x99AA, 0xBBCC, 0xDDEE, 0xFF00) && OFFromBigEndian16(addr.sockaddr.in6.sin6_port) == 1234) TEST(@"Parsing an IPv6 #2", R(addr = OFSocketAddressParseIP(@"::", 1234)) && COMPARE_V6(addr, 0, 0, 0, 0, 0, 0, 0, 0) && OFFromBigEndian16(addr.sockaddr.in6.sin6_port) == 1234) TEST(@"Parsing an IPv6 #3", R(addr = OFSocketAddressParseIP(@"aaAa::bBbb", 1234)) && COMPARE_V6(addr, 0xAAAA, 0, 0, 0, 0, 0, 0, 0xBBBB) && OFFromBigEndian16(addr.sockaddr.in6.sin6_port) == 1234) TEST(@"Parsing an IPv6 #4", R(addr = OFSocketAddressParseIP(@"aaAa::", 1234)) && COMPARE_V6(addr, 0xAAAA, 0, 0, 0, 0, 0, 0, 0) && OFFromBigEndian16(addr.sockaddr.in6.sin6_port) == 1234) TEST(@"Parsing an IPv6 #5", R(addr = OFSocketAddressParseIP(@"::aaAa", 1234)) && COMPARE_V6(addr, 0, 0, 0, 0, 0, 0, 0, 0xAAAA) && OFFromBigEndian16(addr.sockaddr.in6.sin6_port) == 1234) EXPECT_EXCEPTION(@"Refusing invalid IPv6 #1", OFInvalidFormatException, OFSocketAddressParseIP(@"1:::2", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv6 #2", OFInvalidFormatException, OFSocketAddressParseIP(@"1: ::2", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv6 #3", OFInvalidFormatException, OFSocketAddressParseIP(@"1:: :2", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv6 #4", OFInvalidFormatException, OFSocketAddressParseIP(@"1::2::3", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv6 #5", OFInvalidFormatException, OFSocketAddressParseIP(@"10000::1", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv6 #6", OFInvalidFormatException, OFSocketAddressParseIP(@"::10000", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv6 #7", OFInvalidFormatException, OFSocketAddressParseIP(@"::1::", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv6 #8", OFInvalidFormatException, OFSocketAddressParseIP(@"1:2:3:4:5:6:7:", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv6 #9", OFInvalidFormatException, OFSocketAddressParseIP(@"1:2:3:4:5:6:7::", 1234)) EXPECT_EXCEPTION(@"Refusing invalid IPv6 #10", OFInvalidFormatException, OFSocketAddressParseIP(@"1:2", 1234)) TEST(@"Port of an IPv6 address", OFSocketAddressPort(&addr) == 1234) SET_V6(addr, 0, 0, 0, 0, 0, 0, 0, 0) TEST(@"Converting an IPv6 to a string #1", [OFSocketAddressString(&addr) isEqual: @"::"]) SET_V6(addr, 0, 0, 0, 0, 0, 0, 0, 1) TEST(@"Converting an IPv6 to a string #2", [OFSocketAddressString(&addr) isEqual: @"::1"]) SET_V6(addr, 1, 0, 0, 0, 0, 0, 0, 0) TEST(@"Converting an IPv6 to a string #3", [OFSocketAddressString(&addr) isEqual: @"1::"]) SET_V6(addr, 0x1122, 0x3344, 0x5566, 0x7788, 0x99AA, 0xBBCC, 0xDDEE, 0xFF00) TEST(@"Converting an IPv6 to a string #4", [OFSocketAddressString(&addr) isEqual: @"1122:3344:5566:7788:99aa:bbcc:ddee:ff00"]) SET_V6(addr, 0x1122, 0x3344, 0x5566, 0x7788, 0x99AA, 0xBBCC, 0xDDEE, 0) TEST(@"Converting an IPv6 to a string #5", [OFSocketAddressString(&addr) isEqual: @"1122:3344:5566:7788:99aa:bbcc:ddee:0"]) SET_V6(addr, 0x1122, 0x3344, 0x5566, 0x7788, 0x99AA, 0xBBCC, 0, 0) TEST(@"Converting an IPv6 to a string #6", [OFSocketAddressString(&addr) isEqual: @"1122:3344:5566:7788:99aa:bbcc::"]) SET_V6(addr, 0, 0x3344, 0x5566, 0x7788, 0x99AA, 0xBBCC, 0xDDEE, 0xFF00) TEST(@"Converting an IPv6 to a string #7", [OFSocketAddressString(&addr) isEqual: @"0:3344:5566:7788:99aa:bbcc:ddee:ff00"]) SET_V6(addr, 0, 0, 0x5566, 0x7788, 0x99AA, 0xBBCC, 0xDDEE, 0xFF00) TEST(@"Converting an IPv6 to a string #8", [OFSocketAddressString(&addr) isEqual: @"::5566:7788:99aa:bbcc:ddee:ff00"]) SET_V6(addr, 0, 0, 0x5566, 0, 0, 0, 0xDDEE, 0xFF00) TEST(@"Converting an IPv6 to a string #9", [OFSocketAddressString(&addr) isEqual: @"0:0:5566::ddee:ff00"]) SET_V6(addr, 0, 0, 0x5566, 0x7788, 0x99AA, 0xBBCC, 0, 0) TEST(@"Converting an IPv6 to a string #10", [OFSocketAddressString(&addr) isEqual: @"::5566:7788:99aa:bbcc:0:0"]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFStreamTests.m from [3c0c93a949] to [12c9753c4d].
1 | /* | < < | | | | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFStream"; @interface StreamTest: OFStream { int state; } @end @implementation StreamTest - (bool)lowlevelIsAtEndOfStream { return (state > 1); } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)size { size_t pageSize = [OFSystemInfo pageSize]; switch (state) { case 0: if (size < 1) return 0; |
︙ | ︙ | |||
63 64 65 66 67 68 69 | @end @implementation TestsAppDelegate (OFStreamTests) - (void)streamTests { void *pool = objc_autoreleasePoolPush(); size_t pageSize = [OFSystemInfo pageSize]; | | | | | | | > > > | | | > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | @end @implementation TestsAppDelegate (OFStreamTests) - (void)streamTests { void *pool = objc_autoreleasePoolPush(); size_t pageSize = [OFSystemInfo pageSize]; StreamTest *test = [[[StreamTest alloc] init] autorelease]; OFString *string; char *cString; cString = OFAllocMemory(pageSize - 2, 1); memset(cString, 'X', pageSize - 3); cString[pageSize - 3] = '\0'; TEST(@"-[readLine] #1", [[test readLine] isEqual: @"foo"]) string = [test readLine]; TEST(@"-[readLine] #2", string != nil && string.length == pageSize - 3 && !strcmp(string.UTF8String, cString)) OFFreeMemory(cString); objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFStringTests.m from [1ca0b0e0e8] to [7a4f20e376].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | #import "TestsAppDelegate.h" #import "OFString.h" #import "OFMutableUTF8String.h" #import "OFUTF8String.h" | > > > > | | | | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #import "TestsAppDelegate.h" #import "OFString.h" #import "OFMutableUTF8String.h" #import "OFUTF8String.h" #ifndef INFINITY # define INFINITY __builtin_inf() #endif static OFString *module; static OFString *const whitespace[] = { @" \r \t\n\t \tasd \t \t\t\r\n", @" \t\t \t\t \t \t" }; static const OFUnichar unicharString[] = { 0xFEFF, 'f', 0xF6, 0xF6, 'b', 0xE4, 'r', 0x1F03A, 0 }; static const OFUnichar swappedUnicharString[] = { 0xFFFE0000, 0x66000000, 0xF6000000, 0xF6000000, 0x62000000, 0xE4000000, 0x72000000, 0x3AF00100, 0 }; static const OFChar16 char16String[] = { 0xFEFF, 'f', 0xF6, 0xF6, 'b', 0xE4, 'r', 0xD83C, 0xDC3A, 0 }; static const OFChar16 swappedChar16String[] = { 0xFFFE, 0x6600, 0xF600, 0xF600, 0x6200, 0xE400, 0x7200, 0x3CD8, 0x3ADC, 0 }; @interface SimpleString: OFString { OFMutableString *_string; |
︙ | ︙ | |||
85 86 87 88 89 90 91 | @throw e; } return self; } - (instancetype)initWithCString: (const char *)cString | | | | | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | @throw e; } return self; } - (instancetype)initWithCString: (const char *)cString encoding: (OFStringEncoding)encoding length: (size_t)length { self = [super init]; @try { _string = [[OFMutableString alloc] initWithCString: cString encoding: encoding length: length]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithUTF16String: (const OFChar16 *)UTF16String length: (size_t)length byteOrder: (OFByteOrder)byteOrder { self = [super init]; @try { _string = [[OFMutableString alloc] initWithUTF16String: UTF16String length: length byteOrder: byteOrder]; } @catch (id e) { [self release]; @throw e; } return self; } - (instancetype)initWithUTF32String: (const OFChar32 *)UTF32String length: (size_t)length byteOrder: (OFByteOrder)byteOrder { self = [super init]; @try { _string = [[OFMutableString alloc] initWithUTF32String: UTF32String length: length |
︙ | ︙ | |||
163 164 165 166 167 168 169 | - (void)dealloc { [_string release]; [super dealloc]; } | | | | < | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | - (void)dealloc { [_string release]; [super dealloc]; } - (OFUnichar)characterAtIndex: (size_t)idx { return [_string characterAtIndex: idx]; } - (size_t)length { return _string.length; } @end @implementation SimpleMutableString + (void)initialize { if (self == [SimpleMutableString class]) [self inheritMethodsFromClass: [SimpleString class]]; } - (void)replaceCharactersInRange: (OFRange)range withString: (OFString *)string { [_string replaceCharactersInRange: range withString: string]; } @end @interface EntityHandler: OFObject <OFStringXMLUnescapingDelegate> @end @implementation EntityHandler |
︙ | ︙ | |||
208 209 210 211 212 213 214 | @end @implementation TestsAppDelegate (OFStringTests) - (void)stringTestsWithClass: (Class)stringClass mutableClass: (Class)mutableStringClass { void *pool = objc_autoreleasePoolPush(); | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | > | > > | | | | | | | > | | | | | > | | | | | | | | | | | | | | | | | > | > | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | < < > | | | | | | < | | | | | | | | | | | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | @end @implementation TestsAppDelegate (OFStringTests) - (void)stringTestsWithClass: (Class)stringClass mutableClass: (Class)mutableStringClass { void *pool = objc_autoreleasePoolPush(); OFMutableString *mutableString1, *mutableString2, *mutableString3; OFString *string; OFArray *array; size_t i; const OFUnichar *characters; const uint16_t *UTF16Characters; OFCharacterSet *characterSet; EntityHandler *entityHandler; #ifdef OF_HAVE_BLOCKS __block int j; __block bool ok; #endif #define C(s) ((OFString *)[stringClass stringWithString: s]) mutableString1 = [mutableStringClass stringWithString: @"täs€"]; mutableString2 = [mutableStringClass string]; mutableString3 = [[mutableString1 copy] autorelease]; TEST(@"-[isEqual:]", [mutableString1 isEqual: mutableString3] && ![mutableString1 isEqual: [[[OFObject alloc] init] autorelease]]) TEST(@"-[compare:]", [mutableString1 compare: mutableString3] == OFOrderedSame && [mutableString1 compare: @""] != OFOrderedSame && [C(@"") compare: @"a"] == OFOrderedAscending && [C(@"a") compare: @"b"] == OFOrderedAscending && [C(@"cd") compare: @"bc"] == OFOrderedDescending && [C(@"ä") compare: @"ö"] == OFOrderedAscending && [C(@"€") compare: @"ß"] == OFOrderedDescending && [C(@"aa") compare: @"z"] == OFOrderedAscending) #ifdef OF_HAVE_UNICODE_TABLES TEST(@"-[caseInsensitiveCompare:]", [C(@"a") caseInsensitiveCompare: @"A"] == OFOrderedSame && [C(@"Ä") caseInsensitiveCompare: @"ä"] == OFOrderedSame && [C(@"я") caseInsensitiveCompare: @"Я"] == OFOrderedSame && [C(@"€") caseInsensitiveCompare: @"ß"] == OFOrderedDescending && [C(@"ß") caseInsensitiveCompare: @"→"] == OFOrderedAscending && [C(@"AA") caseInsensitiveCompare: @"z"] == OFOrderedAscending && [[stringClass stringWithUTF8String: "ABC"] caseInsensitiveCompare: [stringClass stringWithUTF8String: "AbD"]] == [C(@"abc") compare: @"abd"]) #else TEST(@"-[caseInsensitiveCompare:]", [C(@"a") caseInsensitiveCompare: @"A"] == OFOrderedSame && [C(@"AA") caseInsensitiveCompare: @"z"] == OFOrderedAscending && [[stringClass stringWithUTF8String: "ABC"] caseInsensitiveCompare: [stringClass stringWithUTF8String: "AbD"]] == [C(@"abc") compare: @"abd"]) #endif TEST(@"-[hash] is the same if -[isEqual:] is true", mutableString1.hash == mutableString3.hash) TEST(@"-[description]", [mutableString1.description isEqual: mutableString1]) TEST(@"-[appendString:] and -[appendUTF8String:]", R([mutableString2 appendUTF8String: "1𝄞"]) && R([mutableString2 appendString: @"3"]) && R([mutableString1 appendString: mutableString2]) && [mutableString1 isEqual: @"täs€1𝄞3"]) TEST(@"-[appendCharacters:length:]", R([mutableString2 appendCharacters: unicharString + 6 length: 2]) && [mutableString2 isEqual: @"1𝄞3r🀺"]) TEST(@"-[length]", mutableString1.length == 7) TEST(@"-[UTF8StringLength]", mutableString1.UTF8StringLength == 13) TEST(@"-[hash]", mutableString1.hash == 0x705583C0) TEST(@"-[characterAtIndex:]", [mutableString1 characterAtIndex: 0] == 't' && [mutableString1 characterAtIndex: 1] == 0xE4 && [mutableString1 characterAtIndex: 3] == 0x20AC && [mutableString1 characterAtIndex: 5] == 0x1D11E) EXPECT_EXCEPTION(@"Detect out of range in -[characterAtIndex:]", OFOutOfRangeException, [mutableString1 characterAtIndex: 7]) TEST(@"-[reverse]", R([mutableString1 reverse]) && [mutableString1 isEqual: @"3𝄞1€sät"]) mutableString2 = [mutableStringClass stringWithString: @"abc"]; #ifdef OF_HAVE_UNICODE_TABLES TEST(@"-[uppercase]", R([mutableString1 uppercase]) && [mutableString1 isEqual: @"3𝄞1€SÄT"] && R([mutableString2 uppercase]) && [mutableString2 isEqual: @"ABC"]) TEST(@"-[lowercase]", R([mutableString1 lowercase]) && [mutableString1 isEqual: @"3𝄞1€sät"] && R([mutableString2 lowercase]) && [mutableString2 isEqual: @"abc"]) TEST(@"-[uppercaseString]", [[mutableString1 uppercaseString] isEqual: @"3𝄞1€SÄT"]) TEST(@"-[lowercaseString]", R([mutableString1 uppercase]) && [[mutableString1 lowercaseString] isEqual: @"3𝄞1€sät"]) TEST(@"-[capitalizedString]", [C(@"džbla tdžst TDŽST").capitalizedString isEqual: @"Džbla Tdžst Tdžst"]) #else TEST(@"-[uppercase]", R([mutableString1 uppercase]) && [mutableString1 isEqual: @"3𝄞1€SäT"] && R([mutableString2 uppercase]) && [mutableString2 isEqual: @"ABC"]) TEST(@"-[lowercase]", R([mutableString1 lowercase]) && [mutableString1 isEqual: @"3𝄞1€sät"] && R([mutableString2 lowercase]) && [mutableString2 isEqual: @"abc"]) TEST(@"-[uppercaseString]", [mutableString1.uppercaseString isEqual: @"3𝄞1€SäT"]) TEST(@"-[lowercaseString]", R([mutableString1 uppercase]) && [mutableString1.lowercaseString isEqual: @"3𝄞1€sät"]) TEST(@"-[capitalizedString]", [C(@"džbla tdžst TDŽST").capitalizedString isEqual: @"džbla Tdžst TDŽst"]) #endif TEST(@"+[stringWithUTF8String:length:]", (mutableString1 = [mutableStringClass stringWithUTF8String: "\xEF\xBB\xBF" "foobar" length: 6]) && [mutableString1 isEqual: @"foo"]) TEST(@"+[stringWithUTF16String:]", (string = [stringClass stringWithUTF16String: char16String]) && [string isEqual: @"fööbär🀺"] && (string = [stringClass stringWithUTF16String: swappedChar16String]) && [string isEqual: @"fööbär🀺"]) TEST(@"+[stringWithUTF32String:]", (string = [stringClass stringWithUTF32String: unicharString]) && [string isEqual: @"fööbär🀺"] && (string = [stringClass stringWithUTF32String: swappedUnicharString]) && [string isEqual: @"fööbär🀺"]) #ifdef OF_HAVE_FILES TEST(@"+[stringWithContentsOfFile:encoding]", (string = [stringClass stringWithContentsOfFile: @"testfile.txt" encoding: OFStringEncodingISO8859_1]) && [string isEqual: @"testäöü"]) TEST(@"+[stringWithContentsOfURL:encoding]", (string = [stringClass stringWithContentsOfURL: [OFURL fileURLWithPath: @"testfile.txt"] encoding: OFStringEncodingISO8859_1]) && [string isEqual: @"testäöü"]) #endif TEST(@"-[appendUTFString:length:]", R([mutableString1 appendUTF8String: "\xEF\xBB\xBF" "barqux" length: 6]) && [mutableString1 isEqual: @"foobar"]) EXPECT_EXCEPTION(@"Detection of invalid UTF-8 encoding #1", OFInvalidEncodingException, [stringClass stringWithUTF8String: "\xE0\x80"]) EXPECT_EXCEPTION(@"Detection of invalid UTF-8 encoding #2", OFInvalidEncodingException, [stringClass stringWithUTF8String: "\xF0\x80\x80\xC0"]) TEST(@"Conversion of ISO 8859-1 to Unicode", [[stringClass stringWithCString: "\xE4\xF6\xFC" encoding: OFStringEncodingISO8859_1] isEqual: @"äöü"]) #ifdef HAVE_ISO_8859_15 TEST(@"Conversion of ISO 8859-15 to Unicode", [[stringClass stringWithCString: "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE" encoding: OFStringEncodingISO8859_15] isEqual: @"€ŠšŽžŒœŸ"]) #endif #ifdef HAVE_WINDOWS_1252 TEST(@"Conversion of Windows 1252 to Unicode", [[stringClass stringWithCString: "\x80\x82\x83\x84\x85\x86\x87\x88" "\x89\x8A\x8B\x8C\x8E\x91\x92\x93" "\x94\x95\x96\x97\x98\x99\x9A\x9B" "\x9C\x9E\x9F" encoding: OFStringEncodingWindows1252] isEqual: @"€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ"]) #endif #ifdef HAVE_CODEPAGE_437 TEST(@"Conversion of Codepage 437 to Unicode", [[stringClass stringWithCString: "\xB0\xB1\xB2\xDB" encoding: OFStringEncodingCodepage437] isEqual: @"░▒▓█"]) #endif TEST(@"Conversion of Unicode to ASCII #1", !strcmp([C(@"This is a test") cStringWithEncoding: OFStringEncodingASCII], "This is a test")) EXPECT_EXCEPTION(@"Conversion of Unicode to ASCII #2", OFInvalidEncodingException, [C(@"This is a tést") cStringWithEncoding: OFStringEncodingASCII]) TEST(@"Conversion of Unicode to ISO-8859-1 #1", !strcmp([C(@"This is ä test") cStringWithEncoding: OFStringEncodingISO8859_1], "This is \xE4 test")) EXPECT_EXCEPTION(@"Conversion of Unicode to ISO-8859-1 #2", OFInvalidEncodingException, [C(@"This is ä t€st") cStringWithEncoding: OFStringEncodingISO8859_1]) #ifdef HAVE_ISO_8859_15 TEST(@"Conversion of Unicode to ISO-8859-15 #1", !strcmp([C(@"This is ä t€st") cStringWithEncoding: OFStringEncodingISO8859_15], "This is \xE4 t\xA4st")) EXPECT_EXCEPTION(@"Conversion of Unicode to ISO-8859-15 #2", OFInvalidEncodingException, [C(@"This is ä t€st…") cStringWithEncoding: OFStringEncodingISO8859_15]) #endif #ifdef HAVE_WINDOWS_1252 TEST(@"Conversion of Unicode to Windows-1252 #1", !strcmp([C(@"This is ä t€st…") cStringWithEncoding: OFStringEncodingWindows1252], "This is \xE4 t\x80st\x85")) EXPECT_EXCEPTION(@"Conversion of Unicode to Windows-1252 #2", OFInvalidEncodingException, [C(@"This is ä t€st…‼") cStringWithEncoding: OFStringEncodingWindows1252]) #endif #ifdef HAVE_CODEPAGE_437 TEST(@"Conversion of Unicode to Codepage 437 #1", !strcmp([C(@"Tést strîng ░▒▓") cStringWithEncoding: OFStringEncodingCodepage437], "T\x82st str\x8Cng \xB0\xB1\xB2")) EXPECT_EXCEPTION(@"Conversion of Unicode to Codepage 437 #2", OFInvalidEncodingException, [C(@"T€st strîng ░▒▓") cStringWithEncoding: OFStringEncodingCodepage437]) #endif TEST(@"Lossy conversion of Unicode to ASCII", !strcmp([C(@"This is a tést") lossyCStringWithEncoding: OFStringEncodingASCII], "This is a t?st")) TEST(@"Lossy conversion of Unicode to ISO-8859-1", !strcmp([C(@"This is ä t€st") lossyCStringWithEncoding: OFStringEncodingISO8859_1], "This is \xE4 t?st")) #ifdef HAVE_ISO_8859_15 TEST(@"Lossy conversion of Unicode to ISO-8859-15", !strcmp([C(@"This is ä t€st…") lossyCStringWithEncoding: OFStringEncodingISO8859_15], "This is \xE4 t\xA4st?")) #endif #ifdef HAVE_WINDOWS_1252 TEST(@"Lossy conversion of Unicode to Windows-1252", !strcmp([C(@"This is ä t€st…‼") lossyCStringWithEncoding: OFStringEncodingWindows1252], "This is \xE4 t\x80st\x85?")) #endif #ifdef HAVE_CODEPAGE_437 TEST(@"Lossy conversion of Unicode to Codepage 437", !strcmp([C(@"T€st strîng ░▒▓") lossyCStringWithEncoding: OFStringEncodingCodepage437], "T?st str\x8Cng \xB0\xB1\xB2")) #endif TEST(@"+[stringWithFormat:]", [(mutableString1 = [mutableStringClass stringWithFormat: @"%@:%d", @"test", 123]) isEqual: @"test:123"]) TEST(@"-[appendFormat:]", R(([mutableString1 appendFormat: @"%02X", 15])) && [mutableString1 isEqual: @"test:1230F"]) TEST(@"-[rangeOfString:]", [C(@"𝄞öö") rangeOfString: @"öö"].location == 1 && [C(@"𝄞öö") rangeOfString: @"ö"].location == 1 && [C(@"𝄞öö") rangeOfString: @"𝄞"].location == 0 && [C(@"𝄞öö") rangeOfString: @"x"].location == OFNotFound && [C(@"𝄞öö") rangeOfString: @"öö" options: OFStringSearchBackwards].location == 1 && [C(@"𝄞öö") rangeOfString: @"ö" options: OFStringSearchBackwards].location == 2 && [C(@"𝄞öö") rangeOfString: @"𝄞" options: OFStringSearchBackwards].location == 0 && [C(@"𝄞öö") rangeOfString: @"x" options: OFStringSearchBackwards].location == OFNotFound) EXPECT_EXCEPTION( @"Detect out of range in -[rangeOfString:options:range:]", OFOutOfRangeException, [C(@"𝄞öö") rangeOfString: @"ö" options: 0 range: OFRangeMake(3, 1)]) characterSet = [OFCharacterSet characterSetWithCharactersInString: @"cđ"]; TEST(@"-[indexOfCharacterFromSet:]", [C(@"abcđabcđe") indexOfCharacterFromSet: characterSet] == 2 && [C(@"abcđabcđë") indexOfCharacterFromSet: characterSet options: OFStringSearchBackwards] == 7 && [C(@"abcđabcđë") indexOfCharacterFromSet: characterSet options: 0 range: OFRangeMake(4, 4)] == 6 && [C(@"abcđabcđëf") indexOfCharacterFromSet: characterSet options: 0 range: OFRangeMake(8, 2)] == OFNotFound) EXPECT_EXCEPTION( @"Detect out of range in -[indexOfCharacterFromSet:options:range:]", OFOutOfRangeException, [C(@"𝄞öö") indexOfCharacterFromSet: characterSet options: 0 range: OFRangeMake(3, 1)]) TEST(@"-[substringWithRange:]", [[C(@"𝄞öö") substringWithRange: OFRangeMake(1, 1)] isEqual: @"ö"] && [[C(@"𝄞öö") substringWithRange: OFRangeMake(3, 0)] isEqual: @""]) EXPECT_EXCEPTION(@"Detect out of range in -[substringWithRange:] #1", OFOutOfRangeException, [C(@"𝄞öö") substringWithRange: OFRangeMake(2, 2)]) EXPECT_EXCEPTION(@"Detect out of range in -[substringWithRange:] #2", OFOutOfRangeException, [C(@"𝄞öö") substringWithRange: OFRangeMake(4, 0)]) TEST(@"-[stringByAppendingString:]", [[C(@"foo") stringByAppendingString: @"bar"] isEqual: @"foobar"]) TEST(@"-[stringByPrependingString:]", [[C(@"foo") stringByPrependingString: @"bar"] isEqual: @"barfoo"]) |
︙ | ︙ | |||
561 562 563 564 565 566 567 | !C(@"foo/bar").absolutePath && !C(@"foo").absolutePath) # else TEST(@"-[isAbsolutePath]", C(@"/foo").absolutePath && C(@"/foo/bar").absolutePath && !C(@"foo/bar").absolutePath && !C(@"foo").absolutePath) # endif | | | | | | | | | | | > | > | | | | | | | | > > > | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 | !C(@"foo/bar").absolutePath && !C(@"foo").absolutePath) # else TEST(@"-[isAbsolutePath]", C(@"/foo").absolutePath && C(@"/foo/bar").absolutePath && !C(@"foo/bar").absolutePath && !C(@"foo").absolutePath) # endif mutableString1 = [mutableStringClass stringWithString: @"foo"]; # if defined(OF_WINDOWS) || defined(OF_MSDOS) [mutableString1 appendString: @"\\"]; # else [mutableString1 appendString: @"/"]; # endif [mutableString1 appendString: @"bar"]; mutableString2 = [mutableStringClass stringWithString: mutableString1]; # if defined(OF_WINDOWS) || defined(OF_MSDOS) [mutableString2 appendString: @"\\"]; # else [mutableString2 appendString: @"/"]; # endif string = [stringClass stringWithString: mutableString2]; [mutableString2 appendString: @"baz"]; TEST(@"-[stringByAppendingPathComponent:]", [[mutableString1 stringByAppendingPathComponent: @"baz"] isEqual: mutableString2] && [[string stringByAppendingPathComponent: @"baz"] isEqual: mutableString2]) #endif TEST(@"-[hasPrefix:]", [C(@"foobar") hasPrefix: @"foo"] && ![C(@"foobar") hasPrefix: @"foobar0"]) TEST(@"-[hasSuffix:]", [C(@"foobar") hasSuffix: @"bar"] && ![C(@"foobar") hasSuffix: @"foobar0"]) i = 0; TEST(@"-[componentsSeparatedByString:]", (array = [C(@"fooXXbarXXXXbazXXXX") componentsSeparatedByString: @"XX"]) && [[array objectAtIndex: i++] isEqual: @"foo"] && [[array objectAtIndex: i++] isEqual: @"bar"] && [[array objectAtIndex: i++] isEqual: @""] && [[array objectAtIndex: i++] isEqual: @"baz"] && [[array objectAtIndex: i++] isEqual: @""] && [[array objectAtIndex: i++] isEqual: @""] && array.count == i && (array = [C(@"foo") componentsSeparatedByString: @""]) && [[array objectAtIndex: 0] isEqual: @"foo"] && array.count == 1) i = 0; TEST(@"-[componentsSeparatedByString:options:]", (array = [C(@"fooXXbarXXXXbazXXXX") componentsSeparatedByString: @"XX" options: OFStringSkipEmptyComponents]) && [[array objectAtIndex: i++] isEqual: @"foo"] && [[array objectAtIndex: i++] isEqual: @"bar"] && [[array objectAtIndex: i++] isEqual: @"baz"] && array.count == i) characterSet = [OFCharacterSet characterSetWithCharactersInString: @"XYZ"]; i = 0; TEST(@"-[componentsSeparatedByCharactersInSet:]", (array = [C(@"fooXYbarXYZXbazXYXZx") componentsSeparatedByCharactersInSet: characterSet]) && [[array objectAtIndex: i++] isEqual: @"foo"] && [[array objectAtIndex: i++] isEqual: @""] && [[array objectAtIndex: i++] isEqual: @"bar"] && [[array objectAtIndex: i++] isEqual: @""] && [[array objectAtIndex: i++] isEqual: @""] && [[array objectAtIndex: i++] isEqual: @""] && [[array objectAtIndex: i++] isEqual: @"baz"] && [[array objectAtIndex: i++] isEqual: @""] && [[array objectAtIndex: i++] isEqual: @""] && [[array objectAtIndex: i++] isEqual: @""] && [[array objectAtIndex: i++] isEqual: @"x"] && array.count == i) i = 0; TEST(@"-[componentsSeparatedByCharactersInSet:options:]", (array = [C(@"fooXYbarXYZXbazXYXZ") componentsSeparatedByCharactersInSet: characterSet options: OFStringSkipEmptyComponents]) && [[array objectAtIndex: i++] isEqual: @"foo"] && [[array objectAtIndex: i++] isEqual: @"bar"] && [[array objectAtIndex: i++] isEqual: @"baz"] && array.count == i) #ifdef OF_HAVE_FILES # if defined(OF_WINDOWS) TEST(@"+[pathWithComponents:]", [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo", @"bar", @"baz", nil]] isEqual: @"foo\\bar\\baz"] && [[stringClass pathWithComponents: [OFArray arrayWithObjects: |
︙ | ︙ | |||
741 742 743 744 745 746 747 | [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo", nil]] isEqual: @"foo"]) # endif # if defined(OF_WINDOWS) TEST(@"-[pathComponents]", /* c:/tmp */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 | [[stringClass pathWithComponents: [OFArray arrayWithObjects: @"foo", nil]] isEqual: @"foo"]) # endif # if defined(OF_WINDOWS) TEST(@"-[pathComponents]", /* c:/tmp */ (array = C(@"c:/tmp").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"c:/"] && [[array objectAtIndex: 1] isEqual: @"tmp"] && /* c:\tmp\ */ (array = C(@"c:\\tmp\\").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"c:\\"] && [[array objectAtIndex: 1] isEqual: @"tmp"] && /* c:\ */ (array = C(@"c:\\").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"c:\\"] && /* c:/ */ (array = C(@"c:/").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"c:/"] && /* c: */ (array = C(@"c:").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"c:"] && /* foo\bar */ (array = C(@"foo\\bar").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"foo"] && [[array objectAtIndex: 1] isEqual: @"bar"] && /* foo\bar/baz/ */ (array = C(@"foo\\bar/baz/").pathComponents) && array.count == 3 && [[array objectAtIndex: 0] isEqual: @"foo"] && [[array objectAtIndex: 1] isEqual: @"bar"] && [[array objectAtIndex: 2] isEqual: @"baz"] && /* foo\/ */ (array = C(@"foo\\/").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"foo"] && /* \\foo\bar */ (array = C(@"\\\\foo\\bar").pathComponents) && array.count == 3 && [[array objectAtIndex: 0] isEqual: @"\\\\"] && [[array objectAtIndex: 1] isEqual: @"foo"] && [[array objectAtIndex: 2] isEqual: @"bar"] && C(@"").pathComponents.count == 0) # elif defined(OF_MSDOS) TEST(@"-[pathComponents]", /* c:/tmp */ (array = C(@"c:/tmp").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"c:/"] && [[array objectAtIndex: 1] isEqual: @"tmp"] && /* c:\tmp\ */ (array = C(@"c:\\tmp\\").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"c:\\"] && [[array objectAtIndex: 1] isEqual: @"tmp"] && /* c:\ */ (array = C(@"c:\\").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"c:\\"] && /* c:/ */ (array = C(@"c:/").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"c:/"] && /* c: */ (array = C(@"c:").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"c:"] && /* foo\bar */ (array = C(@"foo\\bar").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"foo"] && [[array objectAtIndex: 1] isEqual: @"bar"] && /* foo\bar/baz/ */ (array = C(@"foo\\bar/baz/").pathComponents) && array.count == 3 && [[array objectAtIndex: 0] isEqual: @"foo"] && [[array objectAtIndex: 1] isEqual: @"bar"] && [[array objectAtIndex: 2] isEqual: @"baz"] && /* foo\/ */ (array = C(@"foo\\/").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"foo"] && C(@"").pathComponents.count == 0) # elif defined(OF_AMIGAOS) TEST(@"-[pathComponents]", /* dh0:tmp */ (array = C(@"dh0:tmp").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"dh0:"] && [[array objectAtIndex: 1] isEqual: @"tmp"] && /* dh0:tmp/ */ (array = C(@"dh0:tmp/").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"dh0:"] && [[array objectAtIndex: 1] isEqual: @"tmp"] && /* dh0: */ (array = C(@"dh0:/").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"dh0:"] && [[array objectAtIndex: 1] isEqual: @"/"] && /* foo/bar */ (array = C(@"foo/bar").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"foo"] && [[array objectAtIndex: 1] isEqual: @"bar"] && /* foo/bar/baz/ */ (array = C(@"foo/bar/baz/").pathComponents) && array.count == 3 && [[array objectAtIndex: 0] isEqual: @"foo"] && [[array objectAtIndex: 1] isEqual: @"bar"] && [[array objectAtIndex: 2] isEqual: @"baz"] && /* foo// */ (array = C(@"foo//").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"foo"] && [[array objectAtIndex: 1] isEqual: @"/"] && C(@"").pathComponents.count == 0) # elif defined(OF_NINTENDO_3DS) || defined(OF_WII) TEST(@"-[pathComponents]", /* sdmc:/tmp */ (array = C(@"sdmc:/tmp").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"sdmc:"] && [[array objectAtIndex: 1] isEqual: @"tmp"] && /* sdmc:/ */ (array = C(@"sdmc:/").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"sdmc:"] && /* foo/bar */ (array = C(@"foo/bar").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"foo"] && [[array objectAtIndex: 1] isEqual: @"bar"] && /* foo/bar/baz/ */ (array = C(@"foo/bar/baz/").pathComponents) && array.count == 3 && [[array objectAtIndex: 0] isEqual: @"foo"] && [[array objectAtIndex: 1] isEqual: @"bar"] && [[array objectAtIndex: 2] isEqual: @"baz"] && /* foo// */ (array = C(@"foo//").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"foo"] && C(@"").pathComponents.count == 0) # else TEST(@"-[pathComponents]", /* /tmp */ (array = C(@"/tmp").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"/"] && [[array objectAtIndex: 1] isEqual: @"tmp"] && /* /tmp/ */ (array = C(@"/tmp/").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"/"] && [[array objectAtIndex: 1] isEqual: @"tmp"] && /* / */ (array = C(@"/").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"/"] && /* foo/bar */ (array = C(@"foo/bar").pathComponents) && array.count == 2 && [[array objectAtIndex: 0] isEqual: @"foo"] && [[array objectAtIndex: 1] isEqual: @"bar"] && /* foo/bar/baz/ */ (array = C(@"foo/bar/baz/").pathComponents) && array.count == 3 && [[array objectAtIndex: 0] isEqual: @"foo"] && [[array objectAtIndex: 1] isEqual: @"bar"] && [[array objectAtIndex: 2] isEqual: @"baz"] && /* foo// */ (array = C(@"foo//").pathComponents) && array.count == 1 && [[array objectAtIndex: 0] isEqual: @"foo"] && C(@"").pathComponents.count == 0) # endif # if defined(OF_WINDOWS) TEST(@"-[lastPathComponent]", [C(@"c:/tmp").lastPathComponent isEqual: @"tmp"] && [C(@"c:\\tmp\\").lastPathComponent isEqual: @"tmp"] && |
︙ | ︙ | |||
1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 | TEST(@"-[longLongValue]", C(@"1234").longLongValue == 1234 && C(@"\r\n+123 ").longLongValue == 123 && C(@"-500\t").longLongValue == -500 && [C(@"-0x10\t") longLongValueWithBase: 0] == -0x10 && C(@"\t\t\r\n").longLongValue == 0 && [C(@"123f") longLongValueWithBase: 16] == 0x123f && [C(@"\t\n0xABcd\r") longLongValueWithBase: 0] == 0xABCD && [C(@"1234567") longLongValueWithBase: 8] == 01234567 && [C(@"\r\n0123") longLongValueWithBase: 0] == 0123 && [C(@"765\t") longLongValueWithBase: 8] == 0765 && [C(@"\t\t\r\n") longLongValueWithBase: 8] == 0) TEST(@"-[unsignedLongLongValue]", C(@"1234").unsignedLongLongValue == 1234 && C(@"\r\n+123 ").unsignedLongLongValue == 123 && C(@"\t\t\r\n").unsignedLongLongValue == 0 && [C(@"123f") unsignedLongLongValueWithBase: 16] == 0x123f && [C(@"\t\n0xABcd\r") unsignedLongLongValueWithBase: 0] == 0xABCD && [C(@"1234567") unsignedLongLongValueWithBase: 8] == 01234567 && [C(@"\r\n0123") unsignedLongLongValueWithBase: 0] == 0123 && [C(@"765\t") unsignedLongLongValueWithBase: 8] == 0765 && [C(@"\t\t\r\n") unsignedLongLongValueWithBase: 8] == 0) /* * These test numbers can be generated without rounding if we have IEEE * floating point numbers, thus we can use == on them. */ TEST(@"-[floatValue]", C(@"\t-0.25 ").floatValue == -0.25 && C(@"\r\n\tINF\t\n").floatValue == INFINITY && C(@"\r -INFINITY\n").floatValue == -INFINITY && | > > | > | | | | 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 | TEST(@"-[longLongValue]", C(@"1234").longLongValue == 1234 && C(@"\r\n+123 ").longLongValue == 123 && C(@"-500\t").longLongValue == -500 && [C(@"-0x10\t") longLongValueWithBase: 0] == -0x10 && C(@"\t\t\r\n").longLongValue == 0 && [C(@"123f") longLongValueWithBase: 16] == 0x123f && [C(@"-1234") longLongValueWithBase: 0] == -1234 && [C(@"\t\n0xABcd\r") longLongValueWithBase: 0] == 0xABCD && [C(@"1234567") longLongValueWithBase: 8] == 01234567 && [C(@"\r\n0123") longLongValueWithBase: 0] == 0123 && [C(@"765\t") longLongValueWithBase: 8] == 0765 && [C(@"\t\t\r\n") longLongValueWithBase: 8] == 0) TEST(@"-[unsignedLongLongValue]", C(@"1234").unsignedLongLongValue == 1234 && C(@"\r\n+123 ").unsignedLongLongValue == 123 && C(@"\t\t\r\n").unsignedLongLongValue == 0 && [C(@"123f") unsignedLongLongValueWithBase: 16] == 0x123f && [C(@"1234") unsignedLongLongValueWithBase: 0] == 1234 && [C(@"\t\n0xABcd\r") unsignedLongLongValueWithBase: 0] == 0xABCD && [C(@"1234567") unsignedLongLongValueWithBase: 8] == 01234567 && [C(@"\r\n0123") unsignedLongLongValueWithBase: 0] == 0123 && [C(@"765\t") unsignedLongLongValueWithBase: 8] == 0765 && [C(@"\t\t\r\n") unsignedLongLongValueWithBase: 8] == 0) /* * These test numbers can be generated without rounding if we have IEEE * floating point numbers, thus we can use == on them. */ TEST(@"-[floatValue]", C(@"\t-0.25 ").floatValue == -0.25 && C(@"\r\n\tINF\t\n").floatValue == INFINITY && C(@"\r -INFINITY\n").floatValue == -INFINITY && isnan(C(@" NAN\t\t").floatValue) && isnan(C(@" -NaN\t\t").floatValue)) #if !defined(OF_ANDROID) && !defined(OF_SOLARIS) && !defined(OF_HPUX) && \ !defined(OF_DJGPP) && !defined(OF_AMIGAOS_M68K) # define INPUT @"\t-0x1.FFFFFFFFFFFFFP-1020 " # define EXPECTED -0x1.FFFFFFFFFFFFFP-1020 #else /* Android, Solaris, HP-UX, DJGPP and AmigaOS 3 do not accept 0x for strtod() */ # if (!defined(OF_SOLARIS) || !defined(OF_X86)) && !defined(OF_AMIGAOS_M68K) # define INPUT @"\t-0.123456789 " # define EXPECTED -0.123456789 # else /* * Solaris' strtod() has weird rounding on x86, but not on x86_64. * AmigaOS 3 with libnix has weird rounding as well. |
︙ | ︙ | |||
1175 1176 1177 1178 1179 1180 1181 | EXPECT_EXCEPTION(@"Detect out of range in -[unsignedLongLongValue]", OFOutOfRangeException, [C(@"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" @"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF") unsignedLongLongValueWithBase: 16]) | | | | | | > | | | | > | > | | | | > | | > | | | < | > | | | | | | | | | > > | | > | | < | > | | < | | < | | < | | < | > | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | > | | > > | | | > | | > > | | > > | | > | | | | 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 | EXPECT_EXCEPTION(@"Detect out of range in -[unsignedLongLongValue]", OFOutOfRangeException, [C(@"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF" @"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF") unsignedLongLongValueWithBase: 16]) TEST(@"-[characters]", (characters = C(@"fööbär🀺").characters) && !memcmp(characters, unicharString + 1, sizeof(unicharString) - 8)) #ifdef OF_BIG_ENDIAN # define swappedByteOrder OFByteOrderLittleEndian #else # define swappedByteOrder OFByteOrderBigEndian #endif TEST(@"-[UTF16String]", (UTF16Characters = C(@"fööbär🀺").UTF16String) && !memcmp(UTF16Characters, char16String + 1, OFUTF16StringLength(char16String) * 2) && (UTF16Characters = [C(@"fööbär🀺") UTF16StringWithByteOrder: swappedByteOrder]) && !memcmp(UTF16Characters, swappedChar16String + 1, OFUTF16StringLength(swappedChar16String) * 2)) TEST(@"-[UTF16StringLength]", C(@"fööbär🀺").UTF16StringLength == 8) TEST(@"-[UTF32String]", (characters = C(@"fööbär🀺").UTF32String) && !memcmp(characters, unicharString + 1, OFUTF32StringLength(unicharString) * 4) && (characters = [C(@"fööbär🀺") UTF32StringWithByteOrder: swappedByteOrder]) && !memcmp(characters, swappedUnicharString + 1, OFUTF32StringLength(swappedUnicharString) * 4)) #undef swappedByteOrder TEST(@"-[stringByMD5Hashing]", [C(@"asdfoobar").stringByMD5Hashing isEqual: @"184dce2ec49b5422c7cfd8728864db4c"]) TEST(@"-[stringByRIPEMD160Hashing]", [C(@"asdfoobar").stringByRIPEMD160Hashing isEqual: @"021d773b0fac06eb6755ca6aa58a580c980f7f13"]) TEST(@"-[stringBySHA1Hashing]", [C(@"asdfoobar").stringBySHA1Hashing isEqual: @"f5f81ac0a8b5cbfdc4585ec1ad32e7b3a12b9b49"]) TEST(@"-[stringBySHA224Hashing]", [C(@"asdfoobar").stringBySHA224Hashing isEqual: @"5a06822dcbd5a874f67d062b80b9d8a9cb9b5b303960b9da9290c192" ]) TEST(@"-[stringBySHA256Hashing]", [C(@"asdfoobar").stringBySHA256Hashing isEqual: @"28e65b1dcd7f6ce2ea6277b15f87b913628b5500bf7913a2bbf4cedc" @"fa1215f6"]) TEST(@"-[stringBySHA384Hashing]", [C(@"asdfoobar").stringBySHA384Hashing isEqual: @"73286da882ffddca2f45e005cfa6b44f3fc65bfb26db1d087ded2f9c" @"279e5addf8be854044bca0cece073fce28eec7d9"]) TEST(@"-[stringBySHA512Hashing]", [C(@"asdfoobar").stringBySHA512Hashing isEqual: @"0464c427da158b02161bb44a3090bbfc594611ef6a53603640454b56" @"412a9247c3579a329e53a5dc74676b106755e3394f9454a2d4227324" @"2615d32f80437d61"]) characterSet = [OFCharacterSet characterSetWithCharactersInString: @"abfo'_~$🍏"]; TEST(@"-[stringByURLEncodingWithAllowedCharacters:]", [[C(@"foo\"ba'_~$]🍏🍌") stringByURLEncodingWithAllowedCharacters: characterSet] isEqual: @"foo%22ba'_~$%5D🍏%F0%9F%8D%8C"]) TEST(@"-[stringByURLDecoding]", [C(@"foo%20bar%22+%24%F0%9F%8D%8C").stringByURLDecoding isEqual: @"foo bar\"+$🍌"]) TEST(@"-[insertString:atIndex:]", (mutableString1 = [mutableStringClass stringWithString: @"𝄞öööbä€"]) && R([mutableString1 insertString: @"äöü" atIndex: 3]) && [mutableString1 isEqual: @"𝄞ööäöüöbä€"]) EXPECT_EXCEPTION(@"Detect invalid format in -[stringByURLDecoding] " @"#1", OFInvalidFormatException, [C(@"foo%xbar") stringByURLDecoding]) EXPECT_EXCEPTION(@"Detect invalid encoding in -[stringByURLDecoding] " @"#2", OFInvalidEncodingException, [C(@"foo%FFbar") stringByURLDecoding]) TEST(@"-[setCharacter:atIndex:]", (mutableString1 = [mutableStringClass stringWithString: @"abäde"]) && R([mutableString1 setCharacter: 0xF6 atIndex: 2]) && [mutableString1 isEqual: @"aböde"] && R([mutableString1 setCharacter: 'c' atIndex: 2]) && [mutableString1 isEqual: @"abcde"] && R([mutableString1 setCharacter: 0x20AC atIndex: 3]) && [mutableString1 isEqual: @"abc€e"] && R([mutableString1 setCharacter: 'x' atIndex: 1]) && [mutableString1 isEqual: @"axc€e"]) TEST(@"-[deleteCharactersInRange:]", (mutableString1 = [mutableStringClass stringWithString: @"𝄞öööbä€"]) && R([mutableString1 deleteCharactersInRange: OFRangeMake(1, 3)]) && [mutableString1 isEqual: @"𝄞bä€"] && R([mutableString1 deleteCharactersInRange: OFRangeMake(0, 4)]) && [mutableString1 isEqual: @""]) TEST(@"-[replaceCharactersInRange:withString:]", (mutableString1 = [mutableStringClass stringWithString: @"𝄞öööbä€"]) && R([mutableString1 replaceCharactersInRange: OFRangeMake(1, 3) withString: @"äöüß"]) && [mutableString1 isEqual: @"𝄞äöüßbä€"] && R([mutableString1 replaceCharactersInRange: OFRangeMake(4, 2) withString: @"b"]) && [mutableString1 isEqual: @"𝄞äöübä€"] && R([mutableString1 replaceCharactersInRange: OFRangeMake(0, 7) withString: @""]) && [mutableString1 isEqual: @""]) EXPECT_EXCEPTION(@"Detect OoR in -[deleteCharactersInRange:] #1", OFOutOfRangeException, { mutableString1 = [mutableStringClass stringWithString: @"𝄞öö"]; [mutableString1 deleteCharactersInRange: OFRangeMake(2, 2)]; }) EXPECT_EXCEPTION(@"Detect OoR in -[deleteCharactersInRange:] #2", OFOutOfRangeException, [mutableString1 deleteCharactersInRange: OFRangeMake(4, 0)]) EXPECT_EXCEPTION(@"Detect OoR in " @"-[replaceCharactersInRange:withString:] #1", OFOutOfRangeException, [mutableString1 replaceCharactersInRange: OFRangeMake(2, 2) withString: @""]) EXPECT_EXCEPTION(@"Detect OoR in " @"-[replaceCharactersInRange:withString:] #2", OFOutOfRangeException, [mutableString1 replaceCharactersInRange: OFRangeMake(4, 0) withString: @""]) TEST(@"-[replaceOccurrencesOfString:withString:]", (mutableString1 = [mutableStringClass stringWithString: @"asd fo asd fofo asd"]) && R([mutableString1 replaceOccurrencesOfString: @"fo" withString: @"foo"]) && [mutableString1 isEqual: @"asd foo asd foofoo asd"] && (mutableString1 = [mutableStringClass stringWithString: @"XX"]) && R([mutableString1 replaceOccurrencesOfString: @"X" withString: @"XX"]) && [mutableString1 isEqual: @"XXXX"]) TEST(@"-[replaceOccurrencesOfString:withString:options:range:]", (mutableString1 = [mutableStringClass stringWithString: @"foofoobarfoobarfoo"]) && R([mutableString1 replaceOccurrencesOfString: @"oo" withString: @"óò" options: 0 range: OFRangeMake(2, 15)]) && [mutableString1 isEqual: @"foofóòbarfóòbarfoo"]) TEST(@"-[deleteLeadingWhitespaces]", (mutableString1 = [mutableStringClass stringWithString: whitespace[0]]) && R([mutableString1 deleteLeadingWhitespaces]) && [mutableString1 isEqual: @"asd \t \t\t\r\n"] && (mutableString1 = [mutableStringClass stringWithString: whitespace[1]]) && R([mutableString1 deleteLeadingWhitespaces]) && [mutableString1 isEqual: @""]) TEST(@"-[deleteTrailingWhitespaces]", (mutableString1 = [mutableStringClass stringWithString: whitespace[0]]) && R([mutableString1 deleteTrailingWhitespaces]) && [mutableString1 isEqual: @" \r \t\n\t \tasd"] && (mutableString1 = [mutableStringClass stringWithString: whitespace[1]]) && R([mutableString1 deleteTrailingWhitespaces]) && [mutableString1 isEqual: @""]) TEST(@"-[deleteEnclosingWhitespaces]", (mutableString1 = [mutableStringClass stringWithString: whitespace[0]]) && R([mutableString1 deleteEnclosingWhitespaces]) && [mutableString1 isEqual: @"asd"] && (mutableString1 = [mutableStringClass stringWithString: whitespace[1]]) && R([mutableString1 deleteEnclosingWhitespaces]) && [mutableString1 isEqual: @""]) #ifdef OF_HAVE_UNICODE_TABLES TEST(@"-[decomposedStringWithCanonicalMapping]", [C(@"H\xC3\xA4llj\xC3\xB6").decomposedStringWithCanonicalMapping isEqual: @"H\x61\xCC\x88llj\x6F\xCC\x88"]); TEST(@"-[decomposedStringWithCompatibilityMapping]", [C(@"H\xC3\xA4llj\xC3\xB6").decomposedStringWithCompatibilityMapping isEqual: @"H\x61\xCC\x88llj\x6F\xCC\x88"]); #endif TEST(@"-[stringByXMLEscaping]", (string = C(@"<hello> &world'\"!&").stringByXMLEscaping) && [string isEqual: @"<hello> &world'"!&"]) TEST(@"-[stringByXMLUnescaping]", [string.stringByXMLUnescaping isEqual: @"<hello> &world'\"!&"] && [C(@"y").stringByXMLUnescaping isEqual: @"y"] && [C(@"ä").stringByXMLUnescaping isEqual: @"ä"] && [C(@"€").stringByXMLUnescaping isEqual: @"€"] && [C(@"𝄞").stringByXMLUnescaping isEqual: @"𝄞"]) EXPECT_EXCEPTION(@"Detect unknown entities in -[stringByXMLUnescaping]", OFUnknownXMLEntityException, [C(@"&foo;") stringByXMLUnescaping]) |
︙ | ︙ | |||
1379 1380 1381 1382 1383 1384 1385 | EXPECT_EXCEPTION(@"Detect invalid entities in -[stringByXMLUnescaping] " @"#4", OFInvalidFormatException, [C(@"&#g;") stringByXMLUnescaping]) EXPECT_EXCEPTION(@"Detect invalid entities in -[stringByXMLUnescaping] " @"#5", OFInvalidFormatException, [C(@"&#xg;") stringByXMLUnescaping]) TEST(@"-[stringByXMLUnescapingWithDelegate:]", | | | | | 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 | EXPECT_EXCEPTION(@"Detect invalid entities in -[stringByXMLUnescaping] " @"#4", OFInvalidFormatException, [C(@"&#g;") stringByXMLUnescaping]) EXPECT_EXCEPTION(@"Detect invalid entities in -[stringByXMLUnescaping] " @"#5", OFInvalidFormatException, [C(@"&#xg;") stringByXMLUnescaping]) TEST(@"-[stringByXMLUnescapingWithDelegate:]", (entityHandler = [[[EntityHandler alloc] init] autorelease]) && [[C(@"x&foo;y") stringByXMLUnescapingWithDelegate: entityHandler] isEqual: @"xbary"]) #ifdef OF_HAVE_BLOCKS TEST(@"-[stringByXMLUnescapingWithBlock:]", [[C(@"x&foo;y") stringByXMLUnescapingWithBlock: ^ OFString *(OFString *str, OFString *entity) { if ([entity isEqual: @"foo"]) return @"bar"; return nil; }] isEqual: @"xbary"]) j = 0; |
︙ | ︙ |
Modified tests/OFSystemInfoTests.m from [62ec592705] to [9c2137f367].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
23 24 25 26 27 28 29 | - (void)systemInfoTests { void *pool = objc_autoreleasePoolPush(); #ifdef OF_HAVE_FILES OFString *userConfigPath, *userDataPath; #endif | | | | | | | | | | | | | | | | | | | | | | | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | - (void)systemInfoTests { void *pool = objc_autoreleasePoolPush(); #ifdef OF_HAVE_FILES OFString *userConfigPath, *userDataPath; #endif [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeFormat: @"[OFSystemInfo] Page size: %zd\n", [OFSystemInfo pageSize]]; [OFStdOut writeFormat: @"[OFSystemInfo] Number of CPUs: %zd\n", [OFSystemInfo numberOfCPUs]]; [OFStdOut writeFormat: @"[OFSystemInfo] ObjFW version: %@\n", [OFSystemInfo ObjFWVersion]]; [OFStdOut writeFormat: @"[OFSystemInfo] ObjFW version major: %u\n", [OFSystemInfo ObjFWVersionMajor]]; [OFStdOut writeFormat: @"[OFSystemInfo] ObjFW version minor: %u\n", [OFSystemInfo ObjFWVersionMinor]]; [OFStdOut writeFormat: @"[OFSystemInfo] Operating system name: %@\n", [OFSystemInfo operatingSystemName]]; [OFStdOut writeFormat: @"[OFSystemInfo] Operating system version: %@\n", [OFSystemInfo operatingSystemVersion]]; #ifdef OF_HAVE_FILES @try { userConfigPath = [OFSystemInfo userConfigPath]; } @catch (OFNotImplementedException *e) { userConfigPath = @"Not implemented"; } [OFStdOut writeFormat: @"[OFSystemInfo] User config path: %@\n", userConfigPath]; @try { userDataPath = [OFSystemInfo userDataPath]; } @catch (OFNotImplementedException *e) { userDataPath = @"Not implemented"; } [OFStdOut writeFormat: @"[OFSystemInfo] User data path: %@\n", userDataPath]; #endif [OFStdOut writeFormat: @"[OFSystemInfo] CPU vendor: %@\n", [OFSystemInfo CPUVendor]]; [OFStdOut writeFormat: @"[OFSystemInfo] CPU model: %@\n", [OFSystemInfo CPUModel]]; #if defined(OF_X86_64) || defined(OF_X86) [OFStdOut writeFormat: @"[OFSystemInfo] Supports MMX: %d\n", [OFSystemInfo supportsMMX]]; [OFStdOut writeFormat: @"[OFSystemInfo] Supports SSE: %d\n", [OFSystemInfo supportsSSE]]; [OFStdOut writeFormat: @"[OFSystemInfo] Supports SSE2: %d\n", [OFSystemInfo supportsSSE2]]; [OFStdOut writeFormat: @"[OFSystemInfo] Supports SSE3: %d\n", [OFSystemInfo supportsSSE3]]; [OFStdOut writeFormat: @"[OFSystemInfo] Supports SSSE3: %d\n", [OFSystemInfo supportsSSSE3]]; [OFStdOut writeFormat: @"[OFSystemInfo] Supports SSE4.1: %d\n", [OFSystemInfo supportsSSE41]]; [OFStdOut writeFormat: @"[OFSystemInfo] Supports SSE4.2: %d\n", [OFSystemInfo supportsSSE42]]; [OFStdOut writeFormat: @"[OFSystemInfo] Supports AVX: %d\n", [OFSystemInfo supportsAVX]]; [OFStdOut writeFormat: @"[OFSystemInfo] Supports AVX2: %d\n", [OFSystemInfo supportsAVX2]]; [OFStdOut writeFormat: @"[OFSystemInfo] Supports AES-NI: %d\n", [OFSystemInfo supportsAESNI]]; [OFStdOut writeFormat: @"[OFSystemInfo] Supports SHA extensions: %d\n", [OFSystemInfo supportsSHAExtensions]]; #endif #ifdef OF_POWERPC [OFStdOut writeFormat: @"[OFSystemInfo] Supports AltiVec: %d\n", [OFSystemInfo supportsAltiVec]]; #endif objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFTCPSocketTests.m from [549b791525] to [e205251e21].
1 | /* | < < | | | | < | < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFTCPSocket"; @implementation TestsAppDelegate (OFTCPSocketTests) - (void)TCPSocketTests { void *pool = objc_autoreleasePoolPush(); OFTCPSocket *server, *client = nil, *accepted; uint16_t port; char buffer[6]; TEST(@"+[socket]", (server = [OFTCPSocket socket]) && (client = [OFTCPSocket socket])) TEST(@"-[bindToHost:port:]", (port = [server bindToHost: @"127.0.0.1" port: 0])) TEST(@"-[listen]", R([server listen])) TEST(@"-[connectToHost:port:]", R([client connectToHost: @"127.0.0.1" port: port])) TEST(@"-[accept]", (accepted = [server accept])) TEST(@"-[remoteAddress]", [OFSocketAddressString(accepted.remoteAddress) isEqual: @"127.0.0.1"]) TEST(@"-[writeString:]", R([client writeString: @"Hello!"])) TEST(@"-[readIntoBuffer:length:]", [accepted readIntoBuffer: buffer length: 6] && !memcmp(buffer, "Hello!", 6)) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFThreadTests.m from [86faf24c0e] to [3abe7860ab].
1 | /* | < < | | | > | | < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFThread"; @interface TestThread: OFThread @end @implementation TestThread - (id)main { [[OFThread threadDictionary] setObject: @"bar" forKey: @"foo"]; OFEnsure([[[OFThread threadDictionary] objectForKey: @"foo"] isEqual: @"bar"]); return @"success"; } @end @implementation TestsAppDelegate (OFThreadTests) - (void)threadTests { void *pool = objc_autoreleasePoolPush(); TestThread *thread; TEST(@"+[thread]", (thread = [TestThread thread])) TEST(@"-[start]", R([thread start])) TEST(@"-[join]", [[thread join] isEqual: @"success"]) TEST(@"-[threadDictionary]", [[OFThread threadDictionary] objectForKey: @"foo"] == nil) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFUDPSocketTests.m from [555c13caae] to [b882de1802].
1 | /* | < < | | | | < | < | | < < | < < < | > | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFUDPSocket"; @implementation TestsAppDelegate (OFUDPSocketTests) - (void)UDPSocketTests { void *pool = objc_autoreleasePoolPush(); OFUDPSocket *sock; uint16_t port1; OFSocketAddress addr1, addr2, addr3; char buf[6]; TEST(@"+[socket]", (sock = [OFUDPSocket socket])) TEST(@"-[bindToHost:port:]", (port1 = [sock bindToHost: @"127.0.0.1" port: 0])) addr1 = OFSocketAddressParseIP(@"127.0.0.1", port1); TEST(@"-[sendBuffer:length:receiver:]", R([sock sendBuffer: "Hello" length: 6 receiver: &addr1])) TEST(@"-[receiveIntoBuffer:length:sender:]", [sock receiveIntoBuffer: buf length: 6 sender: &addr2] == 6 && !memcmp(buf, "Hello", 6) && [OFSocketAddressString(&addr2) isEqual: @"127.0.0.1"] && OFSocketAddressPort(&addr2) == port1) addr3 = OFSocketAddressParseIP(@"127.0.0.1", port1 + 1); /* * TODO: Move those tests elsewhere as soon as the DNS resolving part * is no longer in OFUDPSocket. */ TEST(@"OFSocketAddressEqual()", OFSocketAddressEqual(&addr1, &addr2) && !OFSocketAddressEqual(&addr1, &addr3)) TEST(@"OFSocketAddressHash()", OFSocketAddressHash(&addr1) == OFSocketAddressHash(&addr2) && OFSocketAddressHash(&addr1) != OFSocketAddressHash(&addr3)) objc_autoreleasePoolPop(pool); } @end |
Added tests/OFUNIXDatagramSocketTests.m version [26b71a4581].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFUNIXDatagramSocket"; @implementation TestsAppDelegate (OFUNIXDatagramSocketTests) - (void)UNIXDatagramSocketTests { void *pool = objc_autoreleasePoolPush(); OFString *path; OFUNIXDatagramSocket *sock; OFSocketAddress address1, address2; char buffer[5]; #if defined(OF_HAVE_FILES) && !defined(OF_IOS) path = [[OFSystemInfo temporaryDirectoryPath] stringByAppendingPathComponent: [[OFUUID UUID] UUIDString]]; #else /* * We can have sockets, including UNIX sockets, while file support is * disabled. * * We also use this code path for iOS, as the temporaryDirectoryPath is * too long on the iOS simulator. */ path = [OFString stringWithFormat: @"/tmp/%@", [[OFUUID UUID] UUIDString]]; #endif TEST(@"+[socket]", (sock = [OFUNIXDatagramSocket socket])) @try { TEST(@"-[bindToPath:]", R(address1 = [sock bindToPath: path])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: case EPERM: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFUNIXDatagramSocket] -[bindToPath:]: " @"UNIX datagram sockets unsupported, skipping " @"tests"]; objc_autoreleasePoolPop(pool); return; default: @throw e; } } @try { TEST(@"-[sendBuffer:length:receiver:]", R([sock sendBuffer: "Hello" length: 5 receiver: &address1])) TEST(@"-[receiveIntoBuffer:length:sender:]", [sock receiveIntoBuffer: buffer length: 5 sender: &address2] == 5 && memcmp(buffer, "Hello", 5) == 0 && OFSocketAddressEqual(&address1, &address2) && OFSocketAddressHash(&address1) == OFSocketAddressHash(&address2)) } @finally { #ifdef OF_HAVE_FILES [[OFFileManager defaultManager] removeItemAtPath: path]; #endif } objc_autoreleasePoolPop(pool); } @end |
Added tests/OFUNIXStreamSocketTests.m version [5aa361cd34].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <errno.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFUNIXStreamSocket"; @implementation TestsAppDelegate (OFUNIXStreamSocketTests) - (void)UNIXStreamSocketTests { void *pool = objc_autoreleasePoolPush(); OFString *path; OFUNIXStreamSocket *sockClient, *sockServer, *sockAccepted; char buffer[5]; #if defined(OF_HAVE_FILES) && !defined(OF_IOS) path = [[OFSystemInfo temporaryDirectoryPath] stringByAppendingPathComponent: [[OFUUID UUID] UUIDString]]; #else /* * We can have sockets, including UNIX sockets, while file support is * disabled. * * We also use this code path for iOS, as the temporaryDirectoryPath is * too long on the iOS simulator. */ path = [OFString stringWithFormat: @"/tmp/%@", [[OFUUID UUID] UUIDString]]; #endif TEST(@"+[socket]", (sockClient = [OFUNIXStreamSocket socket]) && (sockServer = [OFUNIXStreamSocket socket])) @try { TEST(@"-[bindToPath:]", R([sockServer bindToPath: path])) } @catch (OFBindFailedException *e) { switch (e.errNo) { case EAFNOSUPPORT: case EPERM: [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut writeLine: @"\r[OFUNIXStreamSocket] -[bindToPath:]: " @"UNIX stream sockets unsupported, skipping tests"]; objc_autoreleasePoolPop(pool); return; default: @throw e; } } @try { TEST(@"-[listen]", R([sockServer listen])) TEST(@"-[connectToPath:]", R([sockClient connectToPath: path])) TEST(@"-[accept]", (sockAccepted = [sockServer accept])) TEST(@"-[writeBuffer:length:]", R([sockAccepted writeBuffer: "Hello" length: 5])) TEST(@"-[readIntoBuffer:length:]", [sockClient readIntoBuffer: buffer length: 5] == 5 && memcmp(buffer, "Hello", 5) == 0) TEST(@"-[remoteAddress]", OFSocketAddressUNIXPath(sockAccepted.remoteAddress) == nil) } @finally { #ifdef OF_HAVE_FILES [[OFFileManager defaultManager] removeItemAtPath: path]; #endif } objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFURLTests.m from [307ed6832b] to [e63dcbf6b8].
1 | /* | < < | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFURL"; static OFString *URLString = @"ht%3atp://us%3Aer:p%40w@ho%3Ast:1234/" @"pa%3Fth?que%23ry=1&f%26oo=b%3dar#frag%23ment"; @implementation TestsAppDelegate (OFURLTests) - (void)URLTests { void *pool = objc_autoreleasePoolPush(); OFURL *URL1, *URL2, *URL3, *URL4, *URL5, *URL6, *URL7; OFMutableURL *mutableURL; TEST(@"+[URLWithString:]", R(URL1 = [OFURL URLWithString: URLString]) && R(URL2 = [OFURL URLWithString: @"http://foo:80"]) && R(URL3 = [OFURL URLWithString: @"http://bar/"]) && R(URL4 = [OFURL URLWithString: @"file:///etc/passwd"]) && R(URL5 = [OFURL URLWithString: @"http://foo/bar/qux/foo%2fbar"]) && R(URL6 = [OFURL URLWithString: @"https://[12:34::56:abcd]/"]) && R(URL7 = [OFURL URLWithString: @"https://[12:34::56:abcd]:234/"])) EXPECT_EXCEPTION(@"+[URLWithString:] fails with invalid characters #1", OFInvalidFormatException, [OFURL URLWithString: @"ht,tp://foo"]) EXPECT_EXCEPTION(@"+[URLWithString:] fails with invalid characters #2", OFInvalidFormatException, |
︙ | ︙ | |||
68 69 70 71 72 73 74 | [OFURL URLWithString: @"https://[f]:/"]) EXPECT_EXCEPTION(@"+[URLWithString:] fails with invalid characters #8", OFInvalidFormatException, [OFURL URLWithString: @"https://[f]:f/"]) TEST(@"+[URLWithString:relativeToURL:]", | | < | | | < | < | < | < | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | [OFURL URLWithString: @"https://[f]:/"]) EXPECT_EXCEPTION(@"+[URLWithString:] fails with invalid characters #8", OFInvalidFormatException, [OFURL URLWithString: @"https://[f]:f/"]) TEST(@"+[URLWithString:relativeToURL:]", [[[OFURL URLWithString: @"/foo" relativeToURL: URL1] string] isEqual: @"ht%3atp://us%3Aer:p%40w@ho%3Ast:1234/foo"] && [[[OFURL URLWithString: @"foo/bar?q" relativeToURL: [OFURL URLWithString: @"http://h/qux/quux"]] string] isEqual: @"http://h/qux/foo/bar?q"] && [[[OFURL URLWithString: @"foo/bar" relativeToURL: [OFURL URLWithString: @"http://h/qux/?x"]] string] isEqual: @"http://h/qux/foo/bar"] && [[[OFURL URLWithString: @"http://foo/?q" relativeToURL: URL1] string] isEqual: @"http://foo/?q"] && [[[OFURL URLWithString: @"foo" relativeToURL: [OFURL URLWithString: @"http://foo/bar"]] string] isEqual: @"http://foo/foo"] && [[[OFURL URLWithString: @"foo" relativeToURL: [OFURL URLWithString: @"http://foo"]] string] isEqual: @"http://foo/foo"]) EXPECT_EXCEPTION( @"+[URLWithString:relativeToURL:] fails with invalid characters #1", OFInvalidFormatException, [OFURL URLWithString: @"`" relativeToURL: URL1]) EXPECT_EXCEPTION( @"+[URLWithString:relativeToURL:] fails with invalid characters #2", OFInvalidFormatException, [OFURL URLWithString: @"/`" relativeToURL: URL1]) EXPECT_EXCEPTION( @"+[URLWithString:relativeToURL:] fails with invalid characters #3", OFInvalidFormatException, [OFURL URLWithString: @"?`" relativeToURL: URL1]) EXPECT_EXCEPTION( @"+[URLWithString:relativeToURL:] fails with invalid characters #4", OFInvalidFormatException, [OFURL URLWithString: @"#`" relativeToURL: URL1]) #ifdef OF_HAVE_FILES TEST(@"+[fileURLWithPath:]", [[[OFURL fileURLWithPath: @"testfile.txt"] fileSystemRepresentation] isEqual: [[OFFileManager defaultManager].currentDirectoryPath stringByAppendingPathComponent: @"testfile.txt"]]) |
︙ | ︙ | |||
138 139 140 141 142 143 144 | [tmp.host isEqual: @"test"] && [tmp.path isEqual: @"/"] && [tmp.string isEqual: @"file://test/"] && [tmp.fileSystemRepresentation isEqual: @"\\\\test"]) # endif #endif TEST(@"-[string]", | | | | | | | | | | | | | > | | | | | | | | | | | | | > | | > | > | | | | | | | | > | > | > | | > | > > | | > | | | | | | > | | > | | | | | | > | | | | | | | | < | < | < | < | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | [tmp.host isEqual: @"test"] && [tmp.path isEqual: @"/"] && [tmp.string isEqual: @"file://test/"] && [tmp.fileSystemRepresentation isEqual: @"\\\\test"]) # endif #endif TEST(@"-[string]", [URL1.string isEqual: URLString] && [URL2.string isEqual: @"http://foo:80"] && [URL3.string isEqual: @"http://bar/"] && [URL4.string isEqual: @"file:///etc/passwd"]) TEST(@"-[scheme]", [URL1.scheme isEqual: @"ht:tp"] && [URL4.scheme isEqual: @"file"]) TEST(@"-[user]", [URL1.user isEqual: @"us:er"] && URL4.user == nil) TEST(@"-[password]", [URL1.password isEqual: @"p@w"] && URL4.password == nil) TEST(@"-[host]", [URL1.host isEqual: @"ho:st"] && [URL6.host isEqual: @"12:34::56:abcd"] && [URL7.host isEqual: @"12:34::56:abcd"]) TEST(@"-[port]", URL1.port.unsignedShortValue == 1234 && [URL4 port] == nil && URL7.port.unsignedShortValue == 234) TEST(@"-[path]", [URL1.path isEqual: @"/pa?th"] && [URL4.path isEqual: @"/etc/passwd"]) TEST(@"-[pathComponents]", [URL1.pathComponents isEqual: [OFArray arrayWithObjects: @"/", @"pa?th", nil]] && [URL4.pathComponents isEqual: [OFArray arrayWithObjects: @"/", @"etc", @"passwd", nil]] && [URL5.pathComponents isEqual: [OFArray arrayWithObjects: @"/", @"bar", @"qux", @"foo/bar", nil]]) TEST(@"-[lastPathComponent]", [[[OFURL URLWithString: @"http://host/foo//bar/baz"] lastPathComponent] isEqual: @"baz"] && [[[OFURL URLWithString: @"http://host/foo//bar/baz/"] lastPathComponent] isEqual: @"baz"] && [[[OFURL URLWithString: @"http://host/foo/"] lastPathComponent] isEqual: @"foo"] && [[[OFURL URLWithString: @"http://host/"] lastPathComponent] isEqual: @"/"] && [URL5.lastPathComponent isEqual: @"foo/bar"]) TEST(@"-[query]", [URL1.query isEqual: @"que#ry=1&f&oo=b=ar"] && URL4.query == nil) TEST(@"-[queryDictionary]", [URL1.queryDictionary isEqual: [OFDictionary dictionaryWithKeysAndObjects: @"que#ry", @"1", @"f&oo", @"b=ar", nil]]); TEST(@"-[fragment]", [URL1.fragment isEqual: @"frag#ment"] && URL4.fragment == nil) TEST(@"-[copy]", R(URL4 = [[URL1 copy] autorelease])) TEST(@"-[isEqual:]", [URL1 isEqual: URL4] && ![URL2 isEqual: URL3] && [[OFURL URLWithString: @"HTTP://bar/"] isEqual: URL3]) TEST(@"-[hash:]", URL1.hash == URL4.hash && URL2.hash != URL3.hash) EXPECT_EXCEPTION(@"Detection of invalid format", OFInvalidFormatException, [OFURL URLWithString: @"http"]) mutableURL = [OFMutableURL URL]; TEST(@"-[setScheme:]", (mutableURL.scheme = @"ht:tp") && [mutableURL.URLEncodedScheme isEqual: @"ht%3Atp"]) TEST(@"-[setURLEncodedScheme:]", (mutableURL.URLEncodedScheme = @"ht%3Atp") && [mutableURL.scheme isEqual: @"ht:tp"]) EXPECT_EXCEPTION( @"-[setURLEncodedScheme:] with invalid characters fails", OFInvalidFormatException, mutableURL.URLEncodedScheme = @"~") TEST(@"-[setHost:]", (mutableURL.host = @"ho:st") && [mutableURL.URLEncodedHost isEqual: @"ho%3Ast"] && (mutableURL.host = @"12:34:ab") && [mutableURL.URLEncodedHost isEqual: @"[12:34:ab]"] && (mutableURL.host = @"12:34:aB") && [mutableURL.URLEncodedHost isEqual: @"[12:34:aB]"] && (mutableURL.host = @"12:34:g") && [mutableURL.URLEncodedHost isEqual: @"12%3A34%3Ag"]) TEST(@"-[setURLEncodedHost:]", (mutableURL.URLEncodedHost = @"ho%3Ast") && [mutableURL.host isEqual: @"ho:st"] && (mutableURL.URLEncodedHost = @"[12:34]") && [mutableURL.host isEqual: @"12:34"] && (mutableURL.URLEncodedHost = @"[12::ab]") && [mutableURL.host isEqual: @"12::ab"]) EXPECT_EXCEPTION(@"-[setURLEncodedHost:] with invalid characters fails" " #1", OFInvalidFormatException, mutableURL.URLEncodedHost = @"/") EXPECT_EXCEPTION(@"-[setURLEncodedHost:] with invalid characters fails" " #2", OFInvalidFormatException, mutableURL.URLEncodedHost = @"[12:34") EXPECT_EXCEPTION(@"-[setURLEncodedHost:] with invalid characters fails" " #3", OFInvalidFormatException, mutableURL.URLEncodedHost = @"[a::g]") TEST(@"-[setUser:]", (mutableURL.user = @"us:er") && [mutableURL.URLEncodedUser isEqual: @"us%3Aer"]) TEST(@"-[setURLEncodedUser:]", (mutableURL.URLEncodedUser = @"us%3Aer") && [mutableURL.user isEqual: @"us:er"]) EXPECT_EXCEPTION(@"-[setURLEncodedUser:] with invalid characters fails", OFInvalidFormatException, mutableURL.URLEncodedHost = @"/") TEST(@"-[setPassword:]", (mutableURL.password = @"pass:word") && [mutableURL.URLEncodedPassword isEqual: @"pass%3Aword"]) TEST(@"-[setURLEncodedPassword:]", (mutableURL.URLEncodedPassword = @"pass%3Aword") && [mutableURL.password isEqual: @"pass:word"]) EXPECT_EXCEPTION( @"-[setURLEncodedPassword:] with invalid characters fails", OFInvalidFormatException, mutableURL.URLEncodedPassword = @"/") TEST(@"-[setPath:]", (mutableURL.path = @"pa/th@?") && [mutableURL.URLEncodedPath isEqual: @"pa/th@%3F"]) TEST(@"-[setURLEncodedPath:]", (mutableURL.URLEncodedPath = @"pa/th@%3F") && [mutableURL.path isEqual: @"pa/th@?"]) EXPECT_EXCEPTION(@"-[setURLEncodedPath:] with invalid characters fails", OFInvalidFormatException, mutableURL.URLEncodedPath = @"?") TEST(@"-[setQuery:]", (mutableURL.query = @"que/ry?#") && [mutableURL.URLEncodedQuery isEqual: @"que/ry?%23"]) TEST(@"-[setURLEncodedQuery:]", (mutableURL.URLEncodedQuery = @"que/ry?%23") && [mutableURL.query isEqual: @"que/ry?#"]) EXPECT_EXCEPTION( @"-[setURLEncodedQuery:] with invalid characters fails", OFInvalidFormatException, mutableURL.URLEncodedQuery = @"`") TEST(@"-[setQueryDictionary:]", (mutableURL.queryDictionary = [OFDictionary dictionaryWithKeysAndObjects: @"foo&bar", @"baz=qux", @"f=oobar", @"b&azqux", nil]) && [mutableURL.URLEncodedQuery isEqual: @"foo%26bar=baz%3Dqux&f%3Doobar=b%26azqux"]) TEST(@"-[setFragment:]", (mutableURL.fragment = @"frag/ment?#") && [mutableURL.URLEncodedFragment isEqual: @"frag/ment?%23"]) TEST(@"-[setURLEncodedFragment:]", (mutableURL.URLEncodedFragment = @"frag/ment?%23") && [mutableURL.fragment isEqual: @"frag/ment?#"]) EXPECT_EXCEPTION( @"-[setURLEncodedFragment:] with invalid characters fails", OFInvalidFormatException, mutableURL.URLEncodedFragment = @"`") TEST(@"-[URLByAppendingPathComponent:isDirectory:]", [[[OFURL URLWithString: @"file:///foo/bar"] URLByAppendingPathComponent: @"qux" isDirectory: false] isEqual: [OFURL URLWithString: @"file:///foo/bar/qux"]] && [[[OFURL URLWithString: @"file:///foo/bar/"] URLByAppendingPathComponent: @"qux" isDirectory: false] isEqual: [OFURL URLWithString: @"file:///foo/bar/qux"]] && [[[OFURL URLWithString: @"file:///foo/bar/"] URLByAppendingPathComponent: @"qu?x" isDirectory: false] isEqual: [OFURL URLWithString: @"file:///foo/bar/qu%3Fx"]] && [[[OFURL URLWithString: @"file:///foo/bar/"] URLByAppendingPathComponent: @"qu?x" isDirectory: true] isEqual: [OFURL URLWithString: @"file:///foo/bar/qu%3Fx/"]]) TEST(@"-[URLByStandardizingPath]", [[[OFURL URLWithString: @"http://foo/bar/.."] URLByStandardizingPath] isEqual: [OFURL URLWithString: @"http://foo/"]] && [[[OFURL URLWithString: @"http://foo/bar/%2E%2E/../qux/"] |
︙ | ︙ |
Modified tests/OFValueTests.m from [d8e22a71e7] to [545d0b4ed0].
1 | /* | < < | | | | | | < | | | < | | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFValue"; @implementation TestsAppDelegate (OFValueTests) - (void)valueTests { void *pool = objc_autoreleasePoolPush(); OFRange range = OFRangeMake(1, 64), range2; OFPoint point = OFPointMake(1.5f, 3.0f), point2; OFSize size = OFSizeMake(4.5f, 5.0f), size2; OFRect rect = OFRectMake(1.5f, 3.0f, 4.5f, 6.0f), rect2; OFValue *value; void *pointer = &value; TEST(@"+[valueWithBytes:objCType:]", (value = [OFValue valueWithBytes: &range objCType: @encode(OFRange)])) TEST(@"-[objCType]", strcmp(value.objCType, @encode(OFRange)) == 0) TEST(@"-[getValue:size:]", R([value getValue: &range2 size: sizeof(OFRange)]) && OFRangeEqual(range2, range)) EXPECT_EXCEPTION(@"-[getValue:size:] with wrong size throws", OFOutOfRangeException, [value getValue: &range size: sizeof(OFRange) - 1]) TEST(@"+[valueWithPointer:]", (value = [OFValue valueWithPointer: pointer])) TEST(@"-[pointerValue]", value.pointerValue == pointer && [[OFValue valueWithBytes: &pointer |
︙ | ︙ | |||
77 78 79 80 81 82 83 | [[OFValue valueWithBytes: "a" objCType: @encode(char)] nonretainedObjectValue]) TEST(@"+[valueWithRange:]", (value = [OFValue valueWithRange: range])) TEST(@"-[rangeValue]", | | | | | < | | | | | < | | | | | | | | | | | | < | | | | | | | | | | | | < | | | < | | | | < | < | < | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | [[OFValue valueWithBytes: "a" objCType: @encode(char)] nonretainedObjectValue]) TEST(@"+[valueWithRange:]", (value = [OFValue valueWithRange: range])) TEST(@"-[rangeValue]", OFRangeEqual(value.rangeValue, range) && (value = [OFValue valueWithBytes: &range objCType: @encode(OFRange)]) && OFRangeEqual(value.rangeValue, range)) TEST(@"-[getValue:size:] for OFRangeValue", (value = [OFValue valueWithRange: range]) && R([value getValue: &range2 size: sizeof(range2)]) && OFRangeEqual(range2, range)) EXPECT_EXCEPTION(@"-[rangeValue] with wrong size throws", OFOutOfRangeException, [[OFValue valueWithBytes: "a" objCType: @encode(char)] rangeValue]) TEST(@"+[valueWithPoint:]", (value = [OFValue valueWithPoint: point])) TEST(@"-[pointValue]", OFPointEqual(value.pointValue, point) && (value = [OFValue valueWithBytes: &point objCType: @encode(OFPoint)]) && OFPointEqual(value.pointValue, point)) TEST(@"-[getValue:size:] for OFPointValue", (value = [OFValue valueWithPoint: point]) && R([value getValue: &point2 size: sizeof(point2)]) && OFPointEqual(point2, point)) EXPECT_EXCEPTION(@"-[pointValue] with wrong size throws", OFOutOfRangeException, [[OFValue valueWithBytes: "a" objCType: @encode(char)] pointValue]) TEST(@"+[valueWithSize:]", (value = [OFValue valueWithSize: size])) TEST(@"-[sizeValue]", OFSizeEqual(value.sizeValue, size) && (value = [OFValue valueWithBytes: &size objCType: @encode(OFSize)]) && OFSizeEqual(value.sizeValue, size)) TEST(@"-[getValue:size:] for OFSizeValue", (value = [OFValue valueWithSize: size]) && R([value getValue: &size2 size: sizeof(size2)]) && OFSizeEqual(size2, size)) EXPECT_EXCEPTION(@"-[sizeValue] with wrong size throws", OFOutOfRangeException, [[OFValue valueWithBytes: "a" objCType: @encode(char)] sizeValue]) TEST(@"+[valueWithRect:]", (value = [OFValue valueWithRect: rect])) TEST(@"-[rectValue]", OFRectEqual(value.rectValue, rect) && (value = [OFValue valueWithBytes: &rect objCType: @encode(OFRect)]) && OFRectEqual(value.rectValue, rect)) TEST(@"-[getValue:size:] for OFRectValue", (value = [OFValue valueWithRect: rect]) && R([value getValue: &rect2 size: sizeof(rect2)]) && OFRectEqual(rect2, rect)) EXPECT_EXCEPTION(@"-[rectValue] with wrong size throws", OFOutOfRangeException, [[OFValue valueWithBytes: "a" objCType: @encode(char)] rectValue]) TEST(@"-[isEqual:]", [[OFValue valueWithRect: rect] isEqual: [OFValue valueWithBytes: &rect objCType: @encode(OFRect)]] && ![[OFValue valueWithBytes: "a" objCType: @encode(signed char)] isEqual: [OFValue valueWithBytes: "a" objCType: @encode(unsigned char)]] && ![[OFValue valueWithBytes: "a" objCType: @encode(char)] isEqual: [OFValue valueWithBytes: "b" objCType: @encode(char)]]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFWindowsRegistryKeyTests.m from [814a5cca52] to [60470d17f4].
1 | /* | < < | | | < | | | > > > | | | | < < | < | | | < | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFWindowsRegistryKey"; @implementation TestsAppDelegate (OFWindowsRegistryKeyTests) - (void)windowsRegistryKeyTests { void *pool = objc_autoreleasePoolPush(); OFData *data = [OFData dataWithItems: "abcdef" count: 6]; OFWindowsRegistryKey *softwareKey, *objFWKey; DWORD type; TEST(@"+[OFWindowsRegistryKey classesRootKey]", [OFWindowsRegistryKey classesRootKey]) TEST(@"+[OFWindowsRegistryKey currentConfigKey]", [OFWindowsRegistryKey currentConfigKey]) TEST(@"+[OFWindowsRegistryKey currentUserKey]", [OFWindowsRegistryKey currentUserKey]) TEST(@"+[OFWindowsRegistryKey localMachineKey]", [OFWindowsRegistryKey localMachineKey]) TEST(@"+[OFWindowsRegistryKey usersKey]", [OFWindowsRegistryKey usersKey]) TEST(@"-[openSubkeyAtPath:securityAndAccessRights:] #1", (softwareKey = [[OFWindowsRegistryKey currentUserKey] openSubkeyAtPath: @"Software" securityAndAccessRights: KEY_ALL_ACCESS])) EXPECT_EXCEPTION(@"-[openSubkeyAtPath:securityAndAccessRights:] #2", OFOpenWindowsRegistryKeyFailedException, [[OFWindowsRegistryKey currentUserKey] openSubkeyAtPath: @"nonexistent" securityAndAccessRights: KEY_ALL_ACCESS]) TEST(@"-[createSubkeyAtPath:securityAndAccessRights:]", (objFWKey = [softwareKey createSubkeyAtPath: @"ObjFW" securityAndAccessRights: KEY_ALL_ACCESS])) TEST(@"-[setData:forValueNamed:type:]", R([objFWKey setData: data forValueNamed: @"data" type: REG_BINARY])) TEST(@"-[dataForValueNamed:subkeyPath:flags:type:]", [[objFWKey dataForValueNamed: @"data" type: &type] isEqual: data] && type == REG_BINARY) TEST(@"-[setString:forValueNamed:type:]", R([objFWKey setString: @"foobar" forValueNamed: @"string"]) && R([objFWKey setString: @"%PATH%;foo" forValueNamed: @"expand" type: REG_EXPAND_SZ])) TEST(@"-[stringForValue:subkeyPath:]", [[objFWKey stringForValueNamed: @"string"] isEqual: @"foobar"] && [[objFWKey stringForValueNamed: @"expand" type: &type] isEqual: @"%PATH%;foo"] && type == REG_EXPAND_SZ) TEST(@"-[deleteValueNamed:]", R([objFWKey deleteValueNamed: @"data"])) TEST(@"-[deleteSubkeyAtPath:]", R([softwareKey deleteSubkeyAtPath: @"ObjFW"])) objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFXMLElementBuilderTests.m from [5c6f3fc1cf] to [3226c89147].
1 | /* | < < | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"OFXMLElementBuilder"; static OFXMLNode *nodes[2]; static size_t i = 0; @implementation TestsAppDelegate (OFXMLElementBuilderTests) - (void)elementBuilder: (OFXMLElementBuilder *)builder didBuildElement: (OFXMLElement *)element { OFEnsure(i == 0); nodes[i++] = [element retain]; } - (void)elementBuilder: (OFXMLElementBuilder *)builder didBuildParentlessNode: (OFXMLNode *)node { OFEnsure(i == 1); nodes[i++] = [node retain]; } - (void)XMLElementBuilderTests { void *pool = objc_autoreleasePoolPush(); OFXMLParser *parser = [OFXMLParser parser]; OFXMLElementBuilder *builder = [OFXMLElementBuilder builder]; OFString *string = @"<foo>bar<![CDATA[f<oo]]>baz<qux/>" " <qux xmlns:qux='urn:qux'><?asd?><qux:bar/><x qux:y='z'/></qux>" "</foo>"; parser.delegate = builder; builder.delegate = self; TEST(@"Building elements from parsed XML", R([parser parseString: string]) && nodes[0] != nil && [nodes[0].XMLString isEqual: string] && R([parser parseString: @"<!--foo-->"]) && nodes[1] != nil && [nodes[1].XMLString isEqual: @"<!--foo-->"] && i == 2) [nodes[0] release]; [nodes[1] release]; objc_autoreleasePoolPop(pool); } @end |
Modified tests/OFXMLNodeTests.m from [ec444519ac] to [29eb2048b3].
1 | /* | < < | | | | > > | | | | | | | | < | | | | | | < | | | | | | < | | | | | | | | | < | | < < | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *module; @implementation TestsAppDelegate (OFXMLNodeTests) - (void)XMLNodeTests { void *pool = objc_autoreleasePoolPush(); id node1, node2, node3, node4; OFArray *array; module = @"OFXMLNode"; TEST(@"+[elementWithName:]", (node1 = [OFXMLElement elementWithName: @"foo"]) && [[node1 XMLString] isEqual: @"<foo/>"]) TEST(@"+[elementWithName:stringValue:]", (node2 = [OFXMLElement elementWithName: @"foo" stringValue: @"b&ar"]) && [[node2 XMLString] isEqual: @"<foo>b&ar</foo>"]) TEST(@"+[elementWithName:namespace:]", (node3 = [OFXMLElement elementWithName: @"foo" namespace: @"urn:objfw:test"]) && R([node3 addAttributeWithName: @"test" stringValue: @"test"]) && R([node3 setPrefix: @"objfw-test" forNamespace: @"urn:objfw:test"]) && [[node3 XMLString] isEqual: @"<objfw-test:foo test='test'/>"] && (node4 = [OFXMLElement elementWithName: @"foo" namespace: @"urn:objfw:test"]) && R([node4 addAttributeWithName: @"test" stringValue: @"test"]) && [[node4 XMLString] isEqual: @"<foo xmlns='urn:objfw:test' test='test'/>"]) TEST(@"+[elementWithName:namespace:stringValue:]", (node4 = [OFXMLElement elementWithName: @"foo" namespace: @"urn:objfw:test" stringValue: @"x"]) && R([node4 setPrefix: @"objfw-test" forNamespace: @"urn:objfw:test"]) && [[node4 XMLString] isEqual: @"<objfw-test:foo>x</objfw-test:foo>"]) TEST(@"+[charactersWithString:]", (node4 = [OFXMLCharacters charactersWithString: @"<foo>"]) && [[node4 XMLString] isEqual: @"<foo>"]) TEST(@"+[CDATAWithString:]", (node4 = [OFXMLCDATA CDATAWithString: @"<foo>"]) && [[node4 XMLString] isEqual: @"<![CDATA[<foo>]]>"]); TEST(@"+[commentWithText:]", (node4 = [OFXMLComment commentWithText: @" comment "]) && [[node4 XMLString] isEqual: @"<!-- comment -->"]) module = @"OFXMLElement"; TEST(@"-[addAttributeWithName:stringValue:]", R([node1 addAttributeWithName: @"foo" stringValue: @"b&ar"]) && [[node1 XMLString] isEqual: @"<foo foo='b&ar'/>"] && R([node2 addAttributeWithName: @"foo" stringValue: @"b&ar"]) && [[node2 XMLString] isEqual: @"<foo foo='b&ar'>b&ar</foo>"]) TEST(@"-[setPrefix:forNamespace:]", R([node2 setPrefix: @"objfw-test" forNamespace: @"urn:objfw:test"])) TEST(@"-[addAttributeWithName:namespace:stringValue:]", R([node2 addAttributeWithName: @"foo" namespace: @"urn:objfw:test" stringValue: @"bar"]) && R([node2 addAttributeWithName: @"foo" namespace: @"urn:objfw:test" stringValue: @"ignored"]) && [[node2 XMLString] isEqual: @"<foo foo='b&ar' objfw-test:foo='bar'>b&ar</foo>"]) TEST(@"-[removeAttributeForName:namespace:]", R([node2 removeAttributeForName: @"foo"]) && [[node2 XMLString] isEqual: @"<foo objfw-test:foo='bar'>b&ar</foo>"] && R([node2 removeAttributeForName: @"foo" namespace: @"urn:objfw:test"]) && [[node2 XMLString] isEqual: @"<foo>b&ar</foo>"]) TEST(@"-[addChild:]", R([node1 addChild: [OFXMLElement elementWithName: @"bar"]]) && [[node1 XMLString] isEqual: @"<foo foo='b&ar'><bar/></foo>"] && R([node3 addChild: [OFXMLElement elementWithName: @"bar" namespace: @"urn:objfw:test"]]) && [[node3 XMLString] isEqual: @"<objfw-test:foo test='test'><objfw-test:bar/></objfw-test:foo>"]) TEST(@"+[elementWithXMLString:] and -[stringValue]", [[[OFXMLElement elementWithXMLString: @"<?xml version='1.0' encoding='UTF-8'?>\r\n<x>foo<![CDATA[bar]]>" @"<y>b<!-- fooo -->az</y>qux</x>"] stringValue] isEqual: @"foobarbazqux"]) TEST(@"-[elementsForName:namespace:]", (array = [node3 elementsForName: @"bar" namespace: @"urn:objfw:test"]) && array.count == 1 && [[array.firstObject XMLString] isEqual: @"<bar xmlns='urn:objfw:test'/>"]) TEST(@"-[isEqual:]", [[OFXMLElement elementWithXMLString: @"<foo bar='asd'/>"] isEqual: [OFXMLElement elementWithXMLString: @"<foo bar='asd'></foo>"]] && [[OFXMLElement elementWithXMLString: @"<x><y/></x>"] isEqual: [OFXMLElement elementWithXMLString: @"<x><y></y></x>"]]) |
︙ | ︙ |
Modified tests/OFXMLParserTests.m from [032c647d7b] to [c00f2c66ff].
1 | /* | < < | | | | | | | | | | | | | | > > | | > | > | | > | > | > | | > | | > | > | > | > | > | > | > | > | | > | > | > | > | > | > | > | | > > | | > | > | > | > | | > | > | | > | > | > | > | > | > | > | > | > | > | | | | > | | | | | | | | | | < | | < | | | < | | | | | | | < | < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #include <stdlib.h> #include <string.h> #import "TestsAppDelegate.h" static OFString *const module = @"OFXMLParser"; static int i = 0; enum EventType { eventTypeProcessingInstruction, eventTypeTagOpen, eventTypeTagClose, eventTypeString, eventTypeCDATA, eventTypeComment }; @implementation TestsAppDelegate (OFXMLParser) - (void)parser: (OFXMLParser *)parser didCreateEvent: (enum EventType)type name: (OFString *)name prefix: (OFString *)prefix namespace: (OFString *)namespace attributes: (OFArray *)attrs string: (OFString *)string { OFString *message; i++; message = [OFString stringWithFormat: @"Parsing part #%d", i]; switch (i) { case 1: TEST(message, type == eventTypeProcessingInstruction && [name isEqual: @"xml"] && [string isEqual: @"version='1.0'"]) break; case 2: TEST(message, type == eventTypeProcessingInstruction && [name isEqual: @"p?i"] && string == nil) break; case 3: TEST(message, type == eventTypeTagOpen && [name isEqual: @"root"] && prefix == nil && namespace == nil && attrs.count == 0) break; case 4: TEST(message, type == eventTypeString && [string isEqual: @"\n\n "]) break; case 5: TEST(message, type == eventTypeCDATA && [string isEqual: @"f<]]]oo]"] && parser.lineNumber == 3) break; case 6: TEST(message, type == eventTypeTagOpen && [name isEqual: @"bar"] && prefix == nil && namespace == nil && attrs == nil) break; case 7: TEST(message, type == eventTypeTagClose && [name isEqual: @"bar"] && prefix == nil && namespace == nil && attrs == nil) break; case 8: TEST(message, type == eventTypeString && [string isEqual: @"\n "]) break; case 9: TEST(message, type == eventTypeTagOpen && [name isEqual: @"foobar"] && prefix == nil && [namespace isEqual: @"urn:objfw:test:foobar"] && attrs.count == 1 && /* xmlns attr */ [[[attrs objectAtIndex: 0] name] isEqual: @"xmlns"] && [[attrs objectAtIndex: 0] namespace] == nil && [[[attrs objectAtIndex: 0] stringValue] isEqual: @"urn:objfw:test:foobar"]) break; case 10: TEST(message, type == eventTypeString && [string isEqual: @"\n "]) break; case 11: TEST(message, type == eventTypeTagOpen && [name isEqual: @"qux"] && prefix == nil && [namespace isEqual: @"urn:objfw:test:foobar"] && attrs.count == 1 && /* xmlns:foo attr */ [[[attrs objectAtIndex: 0] name] isEqual: @"foo"] && [[[attrs objectAtIndex: 0] namespace] isEqual: @"http://www.w3.org/2000/xmlns/"] && [[[attrs objectAtIndex: 0] stringValue] isEqual: @"urn:objfw:test:foo"]) break; case 12: TEST(message, type == eventTypeString && [string isEqual: @"\n "]) break; case 13: TEST(message, type == eventTypeTagOpen && [name isEqual: @"bla"] && [prefix isEqual: @"foo"] && [namespace isEqual: @"urn:objfw:test:foo"] && attrs.count == 2 && /* foo:bla attr */ [[[attrs objectAtIndex: 0] name] isEqual: @"bla"] && [[[attrs objectAtIndex: 0] namespace] isEqual: @"urn:objfw:test:foo"] && [[[attrs objectAtIndex: 0] stringValue] isEqual: @"bla"] && /* blafoo attr */ [[[attrs objectAtIndex: 1] name] isEqual: @"blafoo"] && [[attrs objectAtIndex: 1] namespace] == nil && [[[attrs objectAtIndex: 1] stringValue] isEqual: @"foo"]) break; case 14: TEST(message, type == eventTypeString && [string isEqual: @"\n "]) break; case 15: TEST(message, type == eventTypeTagOpen && [name isEqual: @"blup"] && prefix == nil && [namespace isEqual: @"urn:objfw:test:foobar"] && attrs.count == 2 && /* foo:qux attr */ [[[attrs objectAtIndex: 0] name] isEqual: @"qux"] && [[[attrs objectAtIndex: 0] namespace] isEqual: @"urn:objfw:test:foo"] && [[[attrs objectAtIndex: 0] stringValue] isEqual: @"asd"] && /* quxqux attr */ [[[attrs objectAtIndex: 1] name] isEqual: @"quxqux"] && [[attrs objectAtIndex: 1] namespace] == nil && [[[attrs objectAtIndex: 1] stringValue] isEqual: @"test"]) break; case 16: TEST(message, type == eventTypeTagClose && [name isEqual: @"blup"] && prefix == nil && [namespace isEqual: @"urn:objfw:test:foobar"]) break; case 17: TEST(message, type == eventTypeString && [string isEqual: @"\n "]) break; case 18: TEST(message, type == eventTypeTagOpen && [name isEqual: @"bla"] && [prefix isEqual: @"bla"] && [namespace isEqual: @"urn:objfw:test:bla"] && attrs.count == 3 && /* xmlns:bla attr */ [[[attrs objectAtIndex: 0] name] isEqual: @"bla"] && [[[attrs objectAtIndex: 0] namespace] isEqual: @"http://www.w3.org/2000/xmlns/"] && [[[attrs objectAtIndex: 0] stringValue] isEqual: @"urn:objfw:test:bla"] && /* qux attr */ [[[attrs objectAtIndex: 1] name] isEqual: @"qux"] && [[attrs objectAtIndex: 1] namespace] == nil && [[[attrs objectAtIndex: 1] stringValue] isEqual: @"qux"] && /* bla:foo attr */ [[[attrs objectAtIndex: 2] name] isEqual: @"foo"] && [[[attrs objectAtIndex: 2] namespace] isEqual: @"urn:objfw:test:bla"] && [[[attrs objectAtIndex: 2] stringValue] isEqual: @"blafoo"]) break; case 19: TEST(message, type == eventTypeTagClose && [name isEqual: @"bla"] && [prefix isEqual: @"bla"] && [namespace isEqual: @"urn:objfw:test:bla"]) break; case 20: TEST(message, type == eventTypeString && [string isEqual: @"\n "]) break; case 21: TEST(message, type == eventTypeTagOpen && [name isEqual: @"abc"] && prefix == nil && [namespace isEqual: @"urn:objfw:test:abc"] && attrs.count == 3 && /* xmlns attr */ [[[attrs objectAtIndex: 0] name] isEqual: @"xmlns"] && [[attrs objectAtIndex: 0] namespace] == nil && [[[attrs objectAtIndex: 0] stringValue] isEqual: @"urn:objfw:test:abc"] && /* abc attr */ [[[attrs objectAtIndex: 1] name] isEqual: @"abc"] && [[attrs objectAtIndex: 1] namespace] == nil && [[[attrs objectAtIndex: 1] stringValue] isEqual: @"abc"] && /* foo:abc attr */ [[[attrs objectAtIndex: 2] name] isEqual: @"abc"] && [[[attrs objectAtIndex: 2] namespace] isEqual: @"urn:objfw:test:foo"] && [[[attrs objectAtIndex: 2] stringValue] isEqual: @"abc"]) break; case 22: TEST(message, type == eventTypeTagClose && [name isEqual: @"abc"] && prefix == nil && [namespace isEqual: @"urn:objfw:test:abc"]) break; case 23: TEST(message, type == eventTypeString && [string isEqual: @"\n "]) break; case 24: TEST(message, type == eventTypeTagClose && [name isEqual: @"bla"] && [prefix isEqual: @"foo"] && [namespace isEqual: @"urn:objfw:test:foo"]) break; case 25: TEST(message, type == eventTypeString && [string isEqual: @"\n "]) break; case 26: TEST(message, type == eventTypeComment && [string isEqual: @" commänt "]) break; case 27: TEST(message, type == eventTypeString && [string isEqual: @"\n "]) break; case 28: TEST(message, type == eventTypeTagClose && [name isEqual: @"qux"] && prefix == nil && [namespace isEqual: @"urn:objfw:test:foobar"]) break; case 29: TEST(message, type == eventTypeString && [string isEqual: @"\n "]) break; case 30: TEST(message, type == eventTypeTagClose && [name isEqual: @"foobar"] && prefix == nil && [namespace isEqual: @"urn:objfw:test:foobar"]) break; case 31: TEST(message, type == eventTypeString && [string isEqual: @"\n"]) break; case 32: TEST(message, type == eventTypeTagClose && [name isEqual: @"root"] && prefix == nil && namespace == nil); break; } } - (void)parser: (OFXMLParser *)parser foundProcessingInstructionWithTarget: (OFString *)target data: (OFString *)data { [self parser: parser didCreateEvent: eventTypeProcessingInstruction name: target prefix: nil namespace: nil attributes: nil string: data]; } - (void)parser: (OFXMLParser *)parser didStartElement: (OFString *)name prefix: (OFString *)prefix namespace: (OFString *)namespace attributes: (OFArray *)attrs { [self parser: parser didCreateEvent: eventTypeTagOpen name: name prefix: prefix namespace: namespace attributes: attrs string: nil]; } - (void)parser: (OFXMLParser *)parser didEndElement: (OFString *)name prefix: (OFString *)prefix namespace: (OFString *)namespace { [self parser: parser didCreateEvent: eventTypeTagClose name: name prefix: prefix namespace: namespace attributes: nil string: nil]; } - (void)parser: (OFXMLParser *)parser foundCharacters: (OFString *)string { [self parser: parser didCreateEvent: eventTypeString name: nil prefix: nil namespace: nil attributes: nil string: string]; } - (void)parser: (OFXMLParser *)parser foundCDATA: (OFString *)CDATA { [self parser: parser didCreateEvent: eventTypeCDATA name: nil prefix: nil namespace: nil attributes: nil string: CDATA]; } - (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment { [self parser: parser didCreateEvent: eventTypeComment name: nil prefix: nil namespace: nil attributes: nil string: comment]; } - (OFString *)parser: (OFXMLParser *)parser foundUnknownEntityNamed: (OFString *)entity { if ([entity isEqual: @"foo"]) return @"foobar"; return nil; } - (void)XMLParserTests { void *pool = objc_autoreleasePoolPush(); const char *string = "\xEF\xBB\xBF<?xml version='1.0'?><?p?i?>" "<!DOCTYPE foo><root>\r\r" " <![CDATA[f<]]]oo]]]><bar/>\n" " <foobar xmlns='urn:objfw:test:foobar'>\r\n" " <qux xmlns:foo='urn:objfw:test:foo'>\n" " <foo:bla foo:bla = 'bla' blafoo='foo'>\n" " <blup foo:qux='asd' quxqux='test'/>\n" " <bla:bla\r\rxmlns:bla\r=\t\"urn:objfw:test:bla\" qux='qux'\r\n" " bla:foo='blafoo'/>\n" " <abc xmlns='urn:objfw:test:abc' abc='abc' foo:abc='abc'/>\n" " </foo:bla>\n" " <!-- commänt -->\n" " </qux>\n" " </foobar>\n" "</root>"; OFXMLParser *parser; size_t j, length; TEST(@"+[parser]", (parser = [OFXMLParser parser])) TEST(@"-[setDelegate:]", (parser.delegate = self)) /* Simulate a stream where we only get chunks */ length = strlen(string); for (j = 0; j < length; j+= 2) { if (parser.hasFinishedParsing) abort(); if (j + 2 > length) [parser parseBuffer: string + j length: 1]; else [parser parseBuffer: string + j length: 2]; } TEST(@"Checking if everything was parsed", i == 32 && parser.lineNumber == 18) TEST(@"-[hasFinishedParsing]", parser.hasFinishedParsing) TEST(@"Parsing whitespaces after the document", R([parser parseString: @" \t\r\n "])) TEST(@"Parsing comments after the document", R([parser parseString: @" \t<!-- foo -->\r<!--bar-->\n "])) EXPECT_EXCEPTION(@"Detection of junk after the document #1", OFMalformedXMLException, [parser parseString: @"a"]) EXPECT_EXCEPTION(@"Detection of junk after the document #2", OFMalformedXMLException, [parser parseString: @"<!["]) parser = [OFXMLParser parser]; EXPECT_EXCEPTION(@"Detection of invalid XML processing instruction #1", OFMalformedXMLException, [parser parseString: @"<?xml version='2.0'?>"]) parser = [OFXMLParser parser]; EXPECT_EXCEPTION(@"Detection of invalid XML processing instruction #2", OFInvalidEncodingException, [parser parseString: @"<?xml encoding='UTF-7'?>"]) parser = [OFXMLParser parser]; EXPECT_EXCEPTION(@"Detection of invalid XML processing instruction #3", OFMalformedXMLException, [parser parseString: @"<x><?xml?></x>"]) objc_autoreleasePoolPop(pool); } @end |
Modified tests/RuntimeARCTests.m from [951f2e2edf] to [3a41eba7d4].
1 | /* | < < | | > > > > > > > > > > | > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"Runtime (ARC)"; @interface RuntimeARCTest: OFObject @end @implementation RuntimeARCTest - (instancetype)init { self = [super init]; #ifdef OF_WINDOWS /* * Clang has a bug on Windows where it creates an invalid call into * objc_retainAutoreleasedReturnValue(). Work around it by not using an * autoreleased exception. */ @throw [[OFException alloc] init]; #else @throw [OFException exception]; #endif return self; } @end @implementation TestsAppDelegate (RuntimeARCTests) - (void)runtimeARCTests { id object; __weak id weak; EXPECT_EXCEPTION(@"Exceptions in init", OFException, object = [[RuntimeARCTest alloc] init]) object = [[OFObject alloc] init]; weak = object; TEST(@"weakly referencing an object", weak == object) object = nil; TEST(@"weak references becoming nil", weak == nil) } @end |
Modified tests/RuntimeTests.m from [eff11f992f] to [9aa59cf983].
1 | /* | < < | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *const module = @"Runtime"; @interface OFObject (SuperTest) - (id)superTest; @end @interface RuntimeTest: OFObject { |
︙ | ︙ | |||
61 62 63 64 65 66 67 | } @end @implementation TestsAppDelegate (RuntimeTests) - (void)runtimeTests { void *pool = objc_autoreleasePoolPush(); | | | | | | | | | | | | > | | > | | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | } @end @implementation TestsAppDelegate (RuntimeTests) - (void)runtimeTests { void *pool = objc_autoreleasePoolPush(); RuntimeTest *test = [[[RuntimeTest alloc] init] autorelease]; OFString *string, *foo; #ifdef OF_OBJFW_RUNTIME int classID; uintmax_t value; id object; #endif EXPECT_EXCEPTION(@"Calling a non-existent method via super", OFNotImplementedException, [test superTest]) TEST(@"Calling a method via a super with self == nil", [test nilSuperTest] == nil) string = [OFMutableString stringWithString: @"foo"]; foo = @"foo"; test.foo = string; TEST(@"copy, nonatomic properties", [test.foo isEqual: foo] && test.foo != foo && test.foo.retainCount == 1) test.bar = string; TEST(@"retain, atomic properties", test.bar == string && string.retainCount == 3) #ifdef OF_OBJFW_RUNTIME if (sizeof(uintptr_t) == 8) value = 0xDEADBEEFDEADBEF; else if (sizeof(uintptr_t) == 4) value = 0xDEADBEF; else abort(); TEST(@"Tagged pointers", objc_registerTaggedPointerClass([OFString class]) != -1 && (classID = objc_registerTaggedPointerClass([OFNumber class])) != -1 && (object = objc_createTaggedPointer(classID, (uintptr_t)value)) && object_getClass(object) == [OFNumber class] && [object class] == [OFNumber class] && object_getTaggedPointerValue(object) == value && objc_createTaggedPointer(classID, UINTPTR_MAX >> 4) != nil && objc_createTaggedPointer(classID, (UINTPTR_MAX >> 4) + 1) == nil) #endif objc_autoreleasePoolPop(pool); } @end |
Modified tests/TestsAppDelegate.h from [474ebe8ce9] to [453017b72e].
1 | /* | < < | | | | < | | | < | | < | | | | | | | < | | | | | | | | | < | | < | | | < | < | < < < < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "ObjFW.h" #define TEST(test, ...) \ { \ [self outputTesting: test inModule: module]; \ \ if (__VA_ARGS__) \ [self outputSuccess: test inModule: module]; \ else { \ [self outputFailure: test inModule: module]; \ _fails++; \ } \ } #define EXPECT_EXCEPTION(test, exception, code) \ { \ bool caught = false; \ \ [self outputTesting: test inModule: module]; \ \ @try { \ code; \ } @catch (exception *e) { \ caught = true; \ } \ \ if (caught) \ [self outputSuccess: test inModule: module]; \ else { \ [self outputFailure: test inModule: module]; \ _fails++; \ } \ } #define R(...) (__VA_ARGS__, 1) @class OFString; @interface TestsAppDelegate: OFObject <OFApplicationDelegate> { int _fails; } - (void)outputTesting: (OFString *)test inModule: (OFString *)module; - (void)outputSuccess: (OFString *)test inModule: (OFString *)module; - (void)outputFailure: (OFString *)test inModule: (OFString *)module; @end @interface TestsAppDelegate (OFArrayTests) - (void)arrayTests; @end @interface TestsAppDelegate (OFBlockTests) |
︙ | ︙ | |||
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | @interface TestsAppDelegate (OFMD5HashTests) - (void)MD5HashTests; @end @interface TestsAppDelegate (OFMethodSignatureTests) - (void)methodSignatureTests; @end @interface TestsAppDelegate (OFNumberTests) - (void)numberTests; @end @interface TestsAppDelegate (OFObjectTests) - (void)objectTests; @end @interface TestsAppDelegate (OFPropertyListTests) - (void)propertyListTests; @end @interface TestsAppDelegate (OFPluginTests) - (void)pluginTests; | > > > > > > > > | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | @interface TestsAppDelegate (OFMD5HashTests) - (void)MD5HashTests; @end @interface TestsAppDelegate (OFMethodSignatureTests) - (void)methodSignatureTests; @end @interface TestsAppDelegate (OFNotificationCenterTests) - (void)notificationCenterTests; @end @interface TestsAppDelegate (OFNumberTests) - (void)numberTests; @end @interface TestsAppDelegate (OFObjectTests) - (void)objectTests; @end @interface TestsAppDelegate (OFPBKDF2Tests) - (void)PBKDF2Tests; @end @interface TestsAppDelegate (OFPropertyListTests) - (void)propertyListTests; @end @interface TestsAppDelegate (OFPluginTests) - (void)pluginTests; |
︙ | ︙ | |||
182 183 184 185 186 187 188 | - (void)runtimeARCTests; @end @interface TestsAppDelegate (OFRIPEMD160HashTests) - (void)RIPEMD160HashTests; @end | | | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | - (void)runtimeARCTests; @end @interface TestsAppDelegate (OFRIPEMD160HashTests) - (void)RIPEMD160HashTests; @end @interface TestsAppDelegate (OFScryptTests) - (void)scryptTests; @end @interface TestsAppDelegate (OFSHA1HashTests) - (void)SHA1HashTests; @end |
︙ | ︙ | |||
206 207 208 209 210 211 212 | - (void)SHA384HashTests; @end @interface TestsAppDelegate (OFSHA512HashTests) - (void)SHA512HashTests; @end | < < < < | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | - (void)SHA384HashTests; @end @interface TestsAppDelegate (OFSHA512HashTests) - (void)SHA512HashTests; @end @interface TestsAppDelegate (OFSPXSocketTests) - (void)SPXSocketTests; @end @interface TestsAppDelegate (OFSPXStreamSocketTests) - (void)SPXStreamSocketTests; @end |
︙ | ︙ | |||
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | @interface TestsAppDelegate (OFSystemInfoTests) - (void)systemInfoTests; @end @interface TestsAppDelegate (OFHMACTests) - (void)HMACTests; @end @interface TestsAppDelegate (OFStreamTests) - (void)streamTests; @end @interface TestsAppDelegate (OFStringTests) - (void)stringTests; @end @interface TestsAppDelegate (OFTCPSocketTests) - (void)TCPSocketTests; @end @interface TestsAppDelegate (OFThreadTests) - (void)threadTests; @end @interface TestsAppDelegate (OFUDPSocketTests) - (void)UDPSocketTests; @end @interface TestsAppDelegate (OFURLTests) - (void)URLTests; @end @interface TestsAppDelegate (OFValueTests) - (void)valueTests; | > > > > > > > > > > > > | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | @interface TestsAppDelegate (OFSystemInfoTests) - (void)systemInfoTests; @end @interface TestsAppDelegate (OFHMACTests) - (void)HMACTests; @end @interface TestsAppDelegate (OFSocketTests) - (void)socketTests; @end @interface TestsAppDelegate (OFStreamTests) - (void)streamTests; @end @interface TestsAppDelegate (OFStringTests) - (void)stringTests; @end @interface TestsAppDelegate (OFTCPSocketTests) - (void)TCPSocketTests; @end @interface TestsAppDelegate (OFThreadTests) - (void)threadTests; @end @interface TestsAppDelegate (OFUDPSocketTests) - (void)UDPSocketTests; @end @interface TestsAppDelegate (OFUNIXDatagramSocketTests) - (void)UNIXDatagramSocketTests; @end @interface TestsAppDelegate (OFUNIXStreamSocketTests) - (void)UNIXStreamSocketTests; @end @interface TestsAppDelegate (OFURLTests) - (void)URLTests; @end @interface TestsAppDelegate (OFValueTests) - (void)valueTests; |
︙ | ︙ | |||
278 279 280 281 282 283 284 | - (void)XMLNodeTests; @end @interface TestsAppDelegate (OFXMLParserTests) <OFXMLParserDelegate, OFXMLElementBuilderDelegate> - (void)XMLParserTests; @end | < < < < < < < < | 275 276 277 278 279 280 281 | - (void)XMLNodeTests; @end @interface TestsAppDelegate (OFXMLParserTests) <OFXMLParserDelegate, OFXMLElementBuilderDelegate> - (void)XMLParserTests; @end |
Modified tests/TestsAppDelegate.m from [7de17ddfab] to [e90fb7f104].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
49 50 51 52 53 54 55 56 57 | #ifdef OF_NINTENDO_3DS /* Newer versions of libctru started using id as a parameter name. */ # define id id_3ds # include <3ds.h> # undef id #endif #ifdef OF_PSP static int | > > | | | | | | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | #ifdef OF_NINTENDO_3DS /* Newer versions of libctru started using id as a parameter name. */ # define id id_3ds # include <3ds.h> # undef id #endif extern unsigned long OFHashSeed; #ifdef OF_PSP static int exitCallback(int arg1, int arg2, void *arg) { sceKernelExitGame(); return 0; } static int threadCallback(SceSize args, void *argp) { sceKernelRegisterExitCallback( sceKernelCreateCallback("Exit Callback", exitCallback, NULL)); sceKernelSleepThreadCB(); return 0; } #endif int main(int argc, char *argv[]) { #ifdef OF_PSP int tid; #endif #if defined(OF_OBJFW_RUNTIME) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS) /* * This does not work on Win32 if ObjFW is built as a DLL. * * On AmigaOS, some destructors need to be able to send messages. * Calling objc_deinit() via atexit() would result in the runtime being * destructed before for the destructors ran. */ atexit(objc_deinit); #endif /* We need deterministic hashes for tests */ OFHashSeed = 0; #ifdef OF_WII GXRModeObj *rmode; void *xfb; VIDEO_Init(); WPAD_Init(); |
︙ | ︙ | |||
118 119 120 121 122 123 124 | #ifdef OF_PSP pspDebugScreenInit(); sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); | | | | | | | | | | | | < | | < | | | | | < | | | | | | < | | | | | | | | | | | | | | | | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | #ifdef OF_PSP pspDebugScreenInit(); sceCtrlSetSamplingCycle(0); sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL); if ((tid = sceKernelCreateThread("update_thread", threadCallback, 0x11, 0xFA0, 0, 0)) >= 0) sceKernelStartThread(tid, 0, 0); #endif #ifdef OF_NINTENDO_DS consoleDemoInit(); #endif #ifdef OF_NINTENDO_3DS gfxInitDefault(); atexit(gfxExit); consoleInit(GFX_TOP, NULL); #endif #if defined(OF_WII) || defined(OF_PSP) || defined(OF_NINTENDO_DS) || \ defined(OF_NINTENDO_3DS) @try { return OFApplicationMain(&argc, &argv, [[TestsAppDelegate alloc] init]); } @catch (id e) { OFString *string = [OFString stringWithFormat: @"\nRuntime error: Unhandled exception:\n%@\n", e]; OFString *backtrace = [OFString stringWithFormat: @"\nBacktrace:\n %@\n\n", [[e backtrace] componentsJoinedByString: @"\n "]]; [OFStdOut setForegroundColor: [OFColor red]]; [OFStdOut writeString: string]; [OFStdOut writeString: backtrace]; # if defined(OF_WII) [OFStdOut reset]; [OFStdOut writeString: @"Press home button to exit!"]; for (;;) { WPAD_ScanPads(); if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) [OFApplication terminateWithStatus: 1]; VIDEO_WaitVSync(); } # elif defined(OF_PSP) sceKernelSleepThreadCB(); # elif defined(OF_NINTENDO_DS) [OFStdOut reset]; [OFStdOut writeString: @"Press start button to exit!"]; for (;;) { swiWaitForVBlank(); scanKeys(); if (keysDown() & KEY_START) [OFApplication terminateWithStatus: 1]; } # elif defined(OF_NINTENDO_3DS) [OFStdOut reset]; [OFStdOut writeString: @"Press start button to exit!"]; for (;;) { hidScanInput(); if (hidKeysDown() & KEY_START) [OFApplication terminateWithStatus: 1]; gspWaitForVBlank(); } # else abort(); # endif } #else return OFApplicationMain(&argc, &argv, [[TestsAppDelegate alloc] init]); #endif } @implementation TestsAppDelegate - (void)outputTesting: (OFString *)test inModule: (OFString *)module { if (OFStdOut.hasTerminal) { [OFStdOut setForegroundColor: [OFColor yellow]]; [OFStdOut writeFormat: @"[%@] %@: testing...", module, test]; } else [OFStdOut writeFormat: @"[%@] %@: ", module, test]; } - (void)outputSuccess: (OFString *)test inModule: (OFString *)module { if (OFStdOut.hasTerminal) { [OFStdOut setForegroundColor: [OFColor lime]]; [OFStdOut eraseLine]; [OFStdOut writeFormat: @"\r[%@] %@: ok\n", module, test]; } else [OFStdOut writeLine: @"ok"]; } - (void)outputFailure: (OFString *)test inModule: (OFString *)module { if (OFStdOut.hasTerminal) { [OFStdOut setForegroundColor: [OFColor red]]; [OFStdOut eraseLine]; [OFStdOut writeFormat: @"\r[%@] %@: failed\n", module, test]; #ifdef OF_WII [OFStdOut reset]; [OFStdOut writeLine: @"Press A to continue!"]; for (;;) { WPAD_ScanPads(); if (WPAD_ButtonsDown(0) & WPAD_BUTTON_A) return; VIDEO_WaitVSync(); } #endif #ifdef OF_PSP [OFStdOut reset]; [OFStdOut writeLine: @"Press X to continue!"]; for (;;) { SceCtrlData pad; sceCtrlReadBufferPositive(&pad, 1); if (pad.Buttons & PSP_CTRL_CROSS) { for (;;) { sceCtrlReadBufferPositive(&pad, 1); if (!(pad.Buttons & PSP_CTRL_CROSS)) return; } } } #endif #ifdef OF_NINTENDO_DS [OFStdOut reset]; [OFStdOut writeString: @"Press A to continue!"]; for (;;) { swiWaitForVBlank(); scanKeys(); if (keysDown() & KEY_A) break; } #endif #ifdef OF_NINTENDO_3DS [OFStdOut reset]; [OFStdOut writeString: @"Press A to continue!"]; for (;;) { hidScanInput(); if (hidKeysDown() & KEY_A) break; gspWaitForVBlank(); } #endif [OFStdOut writeString: @"\r"]; [OFStdOut reset]; [OFStdOut eraseLine]; } else [OFStdOut writeLine: @"failed"]; } - (void)applicationDidFinishLaunching { #if defined(OF_IOS) && defined(OF_HAVE_FILES) CFBundleRef mainBundle = CFBundleGetMainBundle(); CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); UInt8 resourcesPath[PATH_MAX]; if (!CFURLGetFileSystemRepresentation(resourcesURL, true, resourcesPath, PATH_MAX)) { [OFStdErr writeString: @"Failed to locate resources!\n"]; [OFApplication terminateWithStatus: 1]; } [[OFFileManager defaultManager] changeCurrentDirectoryPath: [OFString stringWithUTF8String: (const char *)resourcesPath]]; #endif #if defined(OF_WII) && defined(OF_HAVE_FILES) |
︙ | ︙ | |||
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | [self dictionaryTests]; [self listTests]; [self setTests]; [self dateTests]; [self valueTests]; [self numberTests]; [self streamTests]; #ifdef OF_HAVE_FILES [self MD5HashTests]; [self RIPEMD160HashTests]; [self SHA1HashTests]; [self SHA224HashTests]; [self SHA256HashTests]; [self SHA384HashTests]; [self SHA512HashTests]; [self HMACTests]; #endif [self PBKDF2Tests]; [self scryptTests]; #if defined(OF_HAVE_FILES) && defined(HAVE_CODEPAGE_437) [self INIFileTests]; #endif #ifdef OF_HAVE_SOCKETS [self socketTests]; [self TCPSocketTests]; [self UDPSocketTests]; | > < < < > > > > | 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | [self dictionaryTests]; [self listTests]; [self setTests]; [self dateTests]; [self valueTests]; [self numberTests]; [self streamTests]; [self notificationCenterTests]; #ifdef OF_HAVE_FILES [self MD5HashTests]; [self RIPEMD160HashTests]; [self SHA1HashTests]; [self SHA224HashTests]; [self SHA256HashTests]; [self SHA384HashTests]; [self SHA512HashTests]; [self HMACTests]; #endif [self PBKDF2Tests]; [self scryptTests]; #if defined(OF_HAVE_FILES) && defined(HAVE_CODEPAGE_437) [self INIFileTests]; #endif #ifdef OF_HAVE_SOCKETS [self socketTests]; [self TCPSocketTests]; [self UDPSocketTests]; # ifdef OF_HAVE_IPX [self IPXSocketTests]; [self SPXSocketTests]; [self SPXStreamSocketTests]; # endif # ifdef OF_HAVE_UNIX_SOCKETS [self UNIXDatagramSocketTests]; [self UNIXStreamSocketTests]; # endif [self kernelEventObserverTests]; #endif #ifdef OF_HAVE_THREADS [self threadTests]; #endif [self URLTests]; #if defined(OF_HAVE_SOCKETS) && defined(OF_HAVE_THREADS) |
︙ | ︙ | |||
379 380 381 382 383 384 385 | [self XMLNodeTests]; [self XMLElementBuilderTests]; #ifdef OF_HAVE_FILES [self serializationTests]; #endif [self JSONTests]; [self propertyListTests]; | < < | | | | | | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | [self XMLNodeTests]; [self XMLElementBuilderTests]; #ifdef OF_HAVE_FILES [self serializationTests]; #endif [self JSONTests]; [self propertyListTests]; #if defined(OF_HAVE_PLUGINS) [self pluginTests]; #endif #ifdef OF_WINDOWS [self windowsRegistryKeyTests]; #endif #ifdef OF_HAVE_SOCKETS [self DNSResolverTests]; #endif [self systemInfoTests]; [self localeTests]; [OFStdOut reset]; #if defined(OF_IOS) [OFStdOut writeFormat: @"%d tests failed!", _fails]; [OFApplication terminateWithStatus: _fails]; #elif defined(OF_WII) [OFStdOut writeString: @"Press home button to exit!"]; for (;;) { WPAD_ScanPads(); if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) [OFApplication terminateWithStatus: _fails]; VIDEO_WaitVSync(); } #elif defined(OF_PSP) [OFStdOut writeFormat: @"%d tests failed!", _fails]; sceKernelSleepThreadCB(); #elif defined(OF_NINTENDO_DS) [OFStdOut writeString: @"Press start button to exit!"]; for (;;) { swiWaitForVBlank(); scanKeys(); if (keysDown() & KEY_START) [OFApplication terminateWithStatus: _fails]; } #elif defined(OF_NINTENDO_3DS) [OFStdOut writeString: @"Press start button to exit!"]; for (;;) { hidScanInput(); if (hidKeysDown() & KEY_START) [OFApplication terminateWithStatus: _fails]; |
︙ | ︙ |
Modified tests/iOS.xcodeproj/project.pbxproj from [feb9f04764] to [2c6fcc5e96].
︙ | ︙ | |||
131 132 133 134 135 136 137 | }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 4BEBFB532013934E002E8710 /* Project object */ = { isa = PBXProject; attributes = { | | | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 4BEBFB532013934E002E8710 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 1330; ORGANIZATIONNAME = "Jonathan Schleifer"; TargetAttributes = { 4BEBFB5A2013934E002E8710 = { CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; }; }; |
︙ | ︙ | |||
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; | > > | 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; |
︙ | ︙ | |||
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; | > > | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; |
︙ | ︙ |
Modified tests/objc_sync/Makefile from [050b215f54] to [0df383ed25].
1 2 3 4 5 6 7 | include ../../extra.mk PROG_NOINST = objc_sync${PROG_SUFFIX} SRCS = test.m include ../../buildsys.mk | < < | > | | | > | | > | > | > | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | include ../../extra.mk PROG_NOINST = objc_sync${PROG_SUFFIX} SRCS = test.m include ../../buildsys.mk .PHONY: run run: rm -f libobjfw.so.${OBJFW_LIB_MAJOR} rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} rm -f objfw${OBJFW_LIB_MAJOR}.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR} rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib rm -f ${OBJFWRT_AMIGA_LIB} if test -f ../../src/libobjfw.so; then \ ${LN_S} ../../src/libobjfw.so libobjfw.so.${OBJFW_LIB_MAJOR}; \ ${LN_S} ../../src/libobjfw.so \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ elif test -f ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/objfw${OBJFW_LIB_MAJOR}.dll; then \ ${LN_S} ../../src/objfw${OBJFW_LIB_MAJOR}.dll \ objfw${OBJFW_LIB_MAJOR}.dll; \ fi if test -f ../../src/libobjfw.dylib; then \ ${LN_S} ../../src/libobjfw.dylib \ libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/libobjfwrt.so; then \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ elif test -f ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll; then \ ${LN_S} ../../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll \ objfwrt${OBJFWRT_LIB_MAJOR}.dll; \ fi if test -f ../../src/runtime/libobjfwrt.dylib; then \ ${LN_S} ../../src/runtime/libobjfwrt.dylib \ libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/${OBJFWRT_AMIGA_LIB}; then \ ${LN_S} ../../src/runtime/${OBJFWRT_AMIGA_LIB} \ ${OBJFWRT_AMIGA_LIB}; \ fi LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ LIBRARY_PATH=.$${LIBRARY_PATH+:}$$LIBRARY_PATH \ ${WRAPPER} ./${PROG_NOINST}; EXIT=$$?; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR}; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ rm -f objfw${OBJFW_LIB_MAJOR}.dll; \ rm -f libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll; \ rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ exit $$EXIT CPPFLAGS += -I../../src -I../../src/runtime -I../.. LIBS := -L../../src -lobjfw \ -L../../src/runtime -L../../src/runtime/linklib ${RUNTIME_LIBS} \ ${LIBS} LD = ${OBJC} |
Modified tests/objc_sync/test.m from [c5bc507290] to [63dc58fd99].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified tests/plugin/TestPlugin.h from [b8f73b745f] to [2f9aa9b796].
1 | /* | < < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" @interface TestPlugin: OFObject - (int)test: (int)num; @end |
Modified tests/plugin/TestPlugin.m from [78de8ec89d] to [5616dbe160].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
26 27 28 29 30 31 32 | { Class class = objc_getClass("TestPlugin"); if (class == Nil) /* * musl has broken dlclose(): Instead of calling the destructor * on dlclose(), they call it on exit(). This of course means | | | | < > | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | { Class class = objc_getClass("TestPlugin"); if (class == Nil) /* * musl has broken dlclose(): Instead of calling the destructor * on dlclose(), they call it on exit(). This of course means * that our tests might have already called objc_deinit() and * the class is already gone. */ return; objc_unregisterClass(class); } #endif @implementation TestPlugin - (int)test: (int)num { return num * 2; } @end Class class(void) { return [TestPlugin class]; } |
Modified tests/serialization.xml from [c1b84078b7] to [d106910237].
1 2 3 4 5 6 7 8 9 10 | <?xml version='1.0' encoding='UTF-8'?> <serialization xmlns='https://objfw.nil.im/serialization' version='1'> <OFMutableDictionary> <key> <OFString>Blub</OFString> </key> <object> <OFString>B"la</OFString> </object> <key> | > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?xml version='1.0' encoding='UTF-8'?> <serialization xmlns='https://objfw.nil.im/serialization' version='1'> <OFMutableDictionary> <key> <OFUUID>01234567-89ab-cdef-fedc-ba9876543210</OFUUID> </key> <object> <OFString>uuid</OFString> </object> <key> <OFString>Blub</OFString> </key> <object> <OFString>B"la</OFString> </object> <key> |
︙ | ︙ |
Modified tests/terminal/Makefile from [58c564f0ae] to [e8770b0b9b].
1 2 3 4 5 6 7 | include ../../extra.mk PROG_NOINST = terminal_tests${PROG_SUFFIX} SRCS = TerminalTests.m include ../../buildsys.mk | < < | > | | | > | | > | > | > | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | include ../../extra.mk PROG_NOINST = terminal_tests${PROG_SUFFIX} SRCS = TerminalTests.m include ../../buildsys.mk .PHONY: run run: rm -f libobjfw.so.${OBJFW_LIB_MAJOR} rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} rm -f objfw${OBJFW_LIB_MAJOR}.dll libobjfw.${OBJFW_LIB_MAJOR}.dylib rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR} rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib rm -f ${OBJFWRT_AMIGA_LIB} if test -f ../../src/libobjfw.so; then \ ${LN_S} ../../src/libobjfw.so libobjfw.so.${OBJFW_LIB_MAJOR}; \ ${LN_S} ../../src/libobjfw.so \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ elif test -f ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/libobjfw.so.${OBJFW_LIB_MAJOR_MINOR} \ libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/objfw${OBJFW_LIB_MAJOR}.dll; then \ ${LN_S} ../../src/objfw${OBJFW_LIB_MAJOR}.dll \ objfw${OBJFW_LIB_MAJOR}.dll; \ fi if test -f ../../src/libobjfw.dylib; then \ ${LN_S} ../../src/libobjfw.dylib \ libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/libobjfwrt.so; then \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ ${LN_S} ../../src/runtime/libobjfwrt.so \ libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ elif test -f ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; then \ ${LN_S} ../../src/runtime/libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR} libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ fi if test -f ../../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll; then \ ${LN_S} ../../src/runtime/objfwrt${OBJFWRT_LIB_MAJOR}.dll \ objfwrt${OBJFWRT_LIB_MAJOR}.dll; \ fi if test -f ../../src/runtime/libobjfwrt.dylib; then \ ${LN_S} ../../src/runtime/libobjfwrt.dylib \ libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ fi if test -f ../../src/runtime/${OBJFWRT_AMIGA_LIB}; then \ ${LN_S} ../../src/runtime/${OBJFWRT_AMIGA_LIB} \ ${OBJFWRT_AMIGA_LIB}; \ fi LD_LIBRARY_PATH=.$${LD_LIBRARY_PATH+:}$$LD_LIBRARY_PATH \ DYLD_LIBRARY_PATH=.$${DYLD_LIBRARY_PATH+:}$$DYLD_LIBRARY_PATH \ LIBRARY_PATH=.$${LIBRARY_PATH+:}$$LIBRARY_PATH \ ${WRAPPER} ./${PROG_NOINST}; EXIT=$$?; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR}; \ rm -f libobjfw.so.${OBJFW_LIB_MAJOR_MINOR}; \ rm -f objfw${OBJFW_LIB_MAJOR}.dll; \ rm -f libobjfw.${OBJFW_LIB_MAJOR}.dylib; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR}; \ rm -f libobjfwrt.so.${OBJFWRT_LIB_MAJOR_MINOR}; \ rm -f objfwrt${OBJFWRT_LIB_MAJOR}.dll; \ rm -f libobjfwrt.${OBJFWRT_LIB_MAJOR}.dylib; \ exit $$EXIT CPPFLAGS += -I../../src -I../../src/exceptions -I../../src/runtime -I../.. LIBS := -L../../src -lobjfw \ -L../../src/runtime -L../../src/runtime/linklib ${RUNTIME_LIBS} \ ${LIBS} LD = ${OBJC} |
Modified tests/terminal/TerminalTests.m from [6c2580f32c] to [eb6cacca17].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
36 37 38 39 40 41 42 | [OFColor maroon], [OFColor red], [OFColor purple], [OFColor fuchsia], [OFColor green], [OFColor lime], [OFColor olive], [OFColor yellow], [OFColor navy], [OFColor blue], [OFColor teal], [OFColor aqua], nil]; size_t i; OFEnumerator OF_GENERIC(OFColor *) *reverseEnumerator; | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | [OFColor maroon], [OFColor red], [OFColor purple], [OFColor fuchsia], [OFColor green], [OFColor lime], [OFColor olive], [OFColor yellow], [OFColor navy], [OFColor blue], [OFColor teal], [OFColor aqua], nil]; size_t i; OFEnumerator OF_GENERIC(OFColor *) *reverseEnumerator; [OFStdOut writeFormat: @"%dx%d\n", OFStdOut.columns, OFStdOut.rows]; i = 0; for (OFColor *color in colors) { [OFStdOut setForegroundColor: color]; [OFStdOut writeFormat: @"%zx", i++]; } [OFStdOut reset]; [OFStdOut writeLine: @"R"]; i = 0; for (OFColor *color in colors) { [OFStdOut setBackgroundColor: color]; [OFStdOut writeFormat: @"%zx", i++]; } [OFStdOut reset]; [OFStdOut writeLine: @"R"]; i = 0; reverseEnumerator = [colors.reversedArray objectEnumerator]; for (OFColor *color in colors) { [OFStdOut setForegroundColor: color]; [OFStdOut setBackgroundColor: [reverseEnumerator nextObject]]; [OFStdOut writeFormat: @"%zx", i++]; } [OFStdOut reset]; [OFStdOut writeLine: @"R"]; for (i = 0; i < colors.count * 2; i++) { if (i % 2) [OFStdOut setBackgroundColor: [colors objectAtIndex: ((i / 2) + 2) % colors.count]]; else [OFStdOut setForegroundColor: [colors objectAtIndex: i / 2]]; [OFStdOut writeFormat: @"%zx", i / 2]; } [OFStdOut reset]; [OFStdOut writeLine: @"R"]; [OFStdOut writeLine: @"Press return"]; [OFStdIn readLine]; [OFStdOut setBackgroundColor: [OFColor green]]; [OFStdOut writeString: @"Hello!"]; [OFThread sleepForTimeInterval: 2]; [OFStdOut eraseLine]; [OFStdOut writeString: @"World!"]; [OFThread sleepForTimeInterval: 2]; [OFStdOut clear]; [OFThread sleepForTimeInterval: 2]; [OFStdOut setCursorPosition: OFPointMake(5, 3)]; [OFStdOut writeString: @"Text at (5, 3)"]; [OFThread sleepForTimeInterval: 2]; [OFStdOut setRelativeCursorPosition: OFPointMake(-2, 0)]; [OFThread sleepForTimeInterval: 2]; [OFStdOut setRelativeCursorPosition: OFPointMake(2, 0)]; [OFThread sleepForTimeInterval: 2]; [OFStdOut setRelativeCursorPosition: OFPointMake(0, -2)]; [OFThread sleepForTimeInterval: 2]; [OFStdOut setRelativeCursorPosition: OFPointMake(0, 2)]; [OFThread sleepForTimeInterval: 2]; [OFStdOut setRelativeCursorPosition: OFPointMake(1, 1)]; [OFThread sleepForTimeInterval: 2]; [OFStdOut setRelativeCursorPosition: OFPointMake(-1, -1)]; [OFThread sleepForTimeInterval: 2]; [OFStdOut setCursorColumn: 2]; [OFThread sleepForTimeInterval: 2]; [OFStdOut reset]; [OFApplication terminate]; } @end |
Modified utils/Makefile from [82be3d0820] to [521b7f89ce].
1 2 3 4 5 6 | include ../extra.mk SUBDIRS += ${OFARC} \ ${OFDNS} \ ${OFHASH} \ ${OFHTTP} \ | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 | include ../extra.mk SUBDIRS += ${OFARC} \ ${OFDNS} \ ${OFHASH} \ ${OFHTTP} \ completions include ../buildsys.mk DISTCLEAN = objfw-config install-extra: objfw-config objfw-compile objfw-new |
︙ | ︙ |
Modified utils/objfw-compile from [8cbd1f94ba] to [3a536375c5].
1 2 | #!/bin/sh # | < < | | 1 2 3 4 5 6 7 8 9 10 | #!/bin/sh # # Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> # # All rights reserved. # # This file is part of ObjFW. It may be distributed under the terms of the # Q Public License 1.0, which can be found in the file LICENSE.QPL included in # the packaging of this file. # |
︙ | ︙ | |||
28 29 30 31 32 33 34 | fi parse_packages() { packages="" while test x"$1" != "x"; do case "$1" in | | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | fi parse_packages() { packages="" while test x"$1" != "x"; do case "$1" in --package) shift packages="$packages --package $1" ;; esac shift done } parse_packages "$@" show_help() { |
︙ | ︙ | |||
120 121 122 123 124 125 126 | lib="no" plugin="no" out_prefix="" out_suffix="" while test x"$1" != "x"; do case "$1" in | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | > > > > < < | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | lib="no" plugin="no" out_prefix="" out_suffix="" while test x"$1" != "x"; do case "$1" in -o|--out) shift out="$1" ;; --lib) if test x"$plugin" = x"yes"; then echo "You can't use --lib and --plugin!" exit 1 fi shift if ! echo "$1" | grep "^[0-9]\+\.[0-9]\+$" >/dev/null; then echo "$1 is not a valid library version!" exit 1 fi export LIB_MAJOR="${1%.*}" export LIB_MINOR="${1#*.}" lib="yes" OBJCFLAGS="$OBJCFLAGS $($OBJFW_CONFIG --lib-cflags)" out_prefix="$($OBJFW_CONFIG --lib-prefix)" out_suffix="$($OBJFW_CONFIG --lib-suffix)" ;; --package) # Already included into the flags. shift ;; --plugin) if test x"$lib" = x"yes"; then echo "You can't use --lib and --plugin!" exit 1 fi plugin="yes" OBJCFLAGS="$OBJCFLAGS $($OBJFW_CONFIG --plugin-cflags)" LDFLAGS="$LDFLAGS $($OBJFW_CONFIG --plugin-ldflags)" out_suffix="$($OBJFW_CONFIG --plugin-suffix)" ;; --arc) OBJCFLAGS="$OBJCFLAGS $($OBJFW_CONFIG --arc)" ;; --builddir) shift builddir="$1" ;; -D) shift CPPFLAGS="$CPPFLAGS -D$1" ;; -D*) CPPFLAGS="$CPPFLAGS $1" ;; -framework) shift LIBS="$LIBS -framework $1" ;; -f*) OBJCFLAGS="$OBJCFLAGS $1" ;; -F) shift LIBS="$LIBS -F$1" ;; -F*) LIBS="$LIBS $1" ;; -g*) OBJCFLAGS="$OBJCFLAGS $1" ;; -I) shift CPPFLAGS="$CPPFLAGS -I$1" ;; -I*) CPPFLAGS="$CPPFLAGS $1" ;; -l) shift LIBS="$LIBS -l$1" ;; -l*) LIBS="$LIBS $1" ;; -L) shift LIBS="$LIBS -L$1" ;; -L*) LIBS="$LIBS $1" ;; -m*) OBJCFLAGS="$OBJCFLAGS $1" ;; -O*) OBJCFLAGS="$OBJCFLAGS $1" ;; -pthread) OBJCFLAGS="$OBJCFLAGS $1" LDFLAGS="$LDFLAGS $1" ;; -std=*) OBJCFLAGS="$OBJCFLAGS $1" ;; -Wl,*) LDFLAGS="$LDFLAGS $1" ;; -W*) OBJCFLAGS="$OBJCFLAGS $1" ;; --help) show_help exit 0 ;; -*) echo "Unknown option: $1" exit 1 ;; *.m) srcs="$srcs $1" ;; *.mm) srcs="$srcs $1" link_stdcpp="yes" ;; *) echo "Only .m and .mm files can be compiled!" 1>&2 exit 1 ;; esac shift done if test x"$out" = x""; then echo "No output name specified! Use -o or --out!" exit 1 fi case "$builddir" in "") ;; */) ;; *) builddir="$builddir/" ;; esac for i in $srcs; do case $i in *.m) if test x"$lib" = x"yes"; then obj="$builddir${i%.m}.lib.o" elif test x"$plugin" = x"yes"; then obj="$builddir${i%.m}.plugin.o" else obj="$builddir${i%.m}.o" fi ;; *.mm) if test x"$lib" = x"yes"; then obj="$builddir${i%.mm}.lib.o" elif test x"$plugin" = x"yes"; then obj="$builddir${i%.mm}.plugin.o" else obj="$builddir${i%.mm}.o" fi ;; esac objs="$objs $obj" build="no" if test ! -f "$obj" -o "$i" -nt "$obj"; then build="yes" else deps=$($OBJC -E -M $CPPFLAGS $OBJCFLAGS $i | sed 's/.*: //' | sed 's/\\//g') for dep in $deps; do test "$dep" -nt $obj && build="yes" done fi if test x"$build" = x"yes"; then link="yes" status_compiling $i mkdir -p "$(dirname $obj)" || status_compile_failed $i $? $OBJC $CPPFLAGS $OBJCFLAGS -c -o $obj $i || \ |
︙ | ︙ |
Modified utils/objfw-config.in from [c6ea4d4954] to [c7e6aa0918].
1 2 | #!/bin/sh # | < < | | 1 2 3 4 5 6 7 8 9 10 | #!/bin/sh # # Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> # # All rights reserved. # # This file is part of ObjFW. It may be distributed under the terms of the # Q Public License 1.0, which can be found in the file LICENSE.QPL included in # the packaging of this file. # |
︙ | ︙ | |||
94 95 96 97 98 99 100 | . "$packagesdir/$1.oc" set +e } parse_packages() { while test x"$1" != "x"; do case "$1" in | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | < | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | . "$packagesdir/$1.oc" set +e } parse_packages() { while test x"$1" != "x"; do case "$1" in --package) shift package_depends_on "$1" ;; esac shift done } parse_packages "$@" flag_printed="no" output_flag() { if test x"$flag_printed" = x"yes"; then printf " %s" "$1" else printf "%s" "$1" flag_printed="yes" fi } while test x"$1" != "x"; do case "$1" in --all) output_flag "$CFLAGS $CPPFLAGS $CXXFLAGS $OBJCFLAGS" output_flag "$LDFLAGS $LDFLAGS_REEXPORT $LDFLAGS_RPATH $LIBS" ;; --arc) output_flag "-fobjc-arc -fobjc-arc-exceptions" ;; --cflags) output_flag "$CFLAGS" ;; --cppflags) output_flag "$CPPFLAGS" ;; --cxxflags) output_flag "$CXXFLAGS" ;; --framework-libs) output_flag "$FRAMEWORK_LIBS" ;; --help) show_help 0 ;; --objc) output_flag "$OBJC" ;; --objcflags) output_flag "$OBJCFLAGS" ;; --libs) output_flag "$LIBS" ;; --lib-cflags) if test x"$LIB_MAJOR" = x"" -o x"$LIB_MINOR" = x""; then echo "LIB_MAJOR and LIB_MINOR need to be set!" 1>&2 exit 1 fi output_flag "$LIB_CFLAGS" ;; --lib-ldflags) if test x"$SHARED_LIB" = x"" -o x"$LIB_MAJOR" = x"" \ -o x"$LIB_MINOR" = x""; then printf "SHARED_LIB, LIB_MAJOR and " 2>&1 echo "LIB_MINOR need to be set!" 1>&2 exit 1 fi output_flag "$LIB_LDFLAGS" ;; --lib-prefix) if test x"$LIB_MAJOR" = x"" -o x"$LIB_MINOR" = x""; then echo "LIB_MAJOR and LIB_MINOR need to be set!" 1>&2 exit 1 fi output_flag "$LIB_PREFIX" ;; --lib-suffix) if test x"$LIB_MAJOR" = x"" -o x"$LIB_MINOR" = x""; then echo "LIB_MAJOR and LIB_MINOR need to be set!" 1>&2 exit 1 fi output_flag "$LIB_SUFFIX" ;; --ldflags) output_flag "$LDFLAGS" ;; --reexport) output_flag "$LDFLAGS_REEXPORT" ;; --rpath) output_flag "$LDFLAGS_RPATH" ;; --package) # Already included into the flags. shift ;; --packages-dir) output_flag "$packagesdir" ;; --plugin-cflags) output_flag "$PLUGIN_CFLAGS" ;; --plugin-ldflags) output_flag "$PLUGIN_LDFLAGS" ;; --plugin-suffix) output_flag "$PLUGIN_SUFFIX" ;; --prog-suffix) output_flag "$PROG_SUFFIX" ;; --static-libs) output_flag "$STATIC_LIBS" ;; --version) output_flag "$VERSION" ;; *) echo "Invalid option: $1" 1>&2 exit 1 ;; esac shift done test x"$flag_printed" = x"yes" && echo exit 0 |
Modified utils/objfw-new from [c18da52b55] to [6a6815b394].
︙ | ︙ | |||
12 13 14 15 16 17 18 | type="$1" name="$2" test -z "$name" && show_help case "$1" in | | | | | | | | | | | | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | type="$1" name="$2" test -z "$name" && show_help case "$1" in app) test -f "$name.m" && already_exists "$name.m" cat >"$name.m" <<__EOF__ #import <ObjFW/ObjFW.h> @interface $name: OFObject <OFApplicationDelegate> @end OF_APPLICATION_DELEGATE($name) @implementation $name - (void)applicationDidFinishLaunching { [OFApplication terminate]; } @end __EOF__ ;; class) test -f "$name.h" && already_exists "$name.h" test -f "$name.m" && already_exists "$name.m" cat >"$name.h" <<__EOF__ #import <ObjFW/ObjFW.h> @interface $name: OFObject @end __EOF__ cat >"$name.m" <<__EOF__ #import "$name.h" @implementation $name @end __EOF__ ;; *) show_help ;; esac |
Modified utils/ofarc/Archive.h from [4953abe2f6] to [c57fe80fee].
1 | /* | < < | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" #import "OFFile.h" #import "OFArray.h" @protocol Archive <OFObject> + (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream mode: (OFString *)mode encoding: (OFStringEncoding)encoding; - (instancetype)initWithStream: (OF_KINDOF(OFStream *))stream mode: (OFString *)mode encoding: (OFStringEncoding)encoding; - (void)listFiles; - (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files; - (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files; @optional - (void)addFiles: (OFArray OF_GENERIC(OFString *) *)files; @end |
Modified utils/ofarc/GZIPArchive.h from [08bf5643f5] to [384191029a].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified utils/ofarc/GZIPArchive.m from [1991cfed6e] to [2e682cb46c].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
28 29 30 31 32 33 34 | static OFArc *app; static void setPermissions(OFString *destination, OFString *source) { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS OFFileManager *fileManager = [OFFileManager defaultManager]; | | | | | | | | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | static OFArc *app; static void setPermissions(OFString *destination, OFString *source) { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS OFFileManager *fileManager = [OFFileManager defaultManager]; OFFileAttributes attributes = [fileManager attributesOfItemAtPath: source]; OFFileAttributeKey key = OFFilePOSIXPermissions; OFFileAttributes destinationAttributes = [OFDictionary dictionaryWithObject: [attributes objectForKey: key] forKey: key]; [fileManager setAttributes: destinationAttributes ofItemAtPath: destination]; #endif } static void setModificationDate(OFString *path, OFGZIPStream *stream) { OFDate *modificationDate = stream.modificationDate; OFFileAttributes attributes; if (modificationDate == nil) return; attributes = [OFDictionary dictionaryWithObject: modificationDate forKey: OFFileModificationDate]; [[OFFileManager defaultManager] setAttributes: attributes ofItemAtPath: path]; } @implementation GZIPArchive + (void)initialize { if (self == [GZIPArchive class]) app = (OFArc *)[OFApplication sharedApplication].delegate; } + (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream mode: (OFString *)mode encoding: (OFStringEncoding)encoding { return [[[self alloc] initWithStream: stream mode: mode encoding: encoding] autorelease]; } - (instancetype)initWithStream: (OF_KINDOF(OFStream *))stream mode: (OFString *)mode encoding: (OFStringEncoding)encoding { self = [super init]; @try { _stream = [[OFGZIPStream alloc] initWithStream: stream mode: mode]; } @catch (id e) { |
︙ | ︙ | |||
98 99 100 101 102 103 104 | [_stream release]; [super dealloc]; } - (void)listFiles { | | | | | < | < | | | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | [_stream release]; [super dealloc]; } - (void)listFiles { [OFStdErr writeLine: OF_LOCALIZED(@"cannot_list_gz", @"Cannot list files of a .gz archive!")]; app->_exitStatus = 1; } - (void)extractFiles: (OFArray OF_GENERIC(OFString *) *)files { OFString *fileName; OFFile *output; if (files.count != 0) { [OFStdErr writeLine: OF_LOCALIZED(@"cannot_extract_specific_file_from_gz", @"Cannot extract a specific file of a .gz archive!")]; app->_exitStatus = 1; return; } fileName = app->_archivePath.lastPathComponent .stringByDeletingPathExtension; if (app->_outputLevel >= 0) [OFStdOut writeString: OF_LOCALIZED(@"extracting_file", @"Extracting %[file]...", @"file", fileName)]; if (![app shouldExtractFile: fileName outFileName: fileName]) return; output = [OFFile fileWithPath: fileName mode: @"w"]; setPermissions(fileName, app->_archivePath); while (!_stream.atEndOfStream) { ssize_t length = [app copyBlockFromStream: _stream toStream: output fileName: fileName]; if (length < 0) { app->_exitStatus = 1; return; } } [output close]; setModificationDate(fileName, _stream); if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED(@"extracting_file_done", @"Extracting %[file]... done", @"file", fileName)]; } } - (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files { OFString *fileName = app->_archivePath.lastPathComponent .stringByDeletingPathExtension; if (files.count > 0) { [OFStdErr writeLine: OF_LOCALIZED( @"cannot_print_specific_file_from_gz", @"Cannot print a specific file of a .gz archive!")]; app->_exitStatus = 1; return; } while (!_stream.atEndOfStream) { ssize_t length = [app copyBlockFromStream: _stream toStream: OFStdOut fileName: fileName]; if (length < 0) { app->_exitStatus = 1; return; } } } @end |
Modified utils/ofarc/LHAArchive.h from [a8594d02df] to [5ad6942309].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified utils/ofarc/LHAArchive.m from [da084987c7] to [fb0bc51e00].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
46 47 48 49 50 51 52 | if (mode == nil) return; mode = [OFNumber numberWithUnsignedShort: mode.unsignedShortValue & 0777]; | | | | | | | | | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | if (mode == nil) return; mode = [OFNumber numberWithUnsignedShort: mode.unsignedShortValue & 0777]; OFFileAttributes attributes = [OFDictionary dictionaryWithObject: mode forKey: OFFilePOSIXPermissions]; [[OFFileManager defaultManager] setAttributes: attributes ofItemAtPath: path]; #endif } static void setModificationDate(OFString *path, OFLHAArchiveEntry *entry) { OFDate *modificationDate = entry.modificationDate; OFFileAttributes attributes; if (modificationDate == nil) { /* * Fall back to the original date if we have no modification * date, as the modification date is a UNIX extension. */ modificationDate = entry.date; if (modificationDate == nil) return; } attributes = [OFDictionary dictionaryWithObject: modificationDate forKey: OFFileModificationDate]; [[OFFileManager defaultManager] setAttributes: attributes ofItemAtPath: path]; } @implementation LHAArchive + (void)initialize { if (self == [LHAArchive class]) app = (OFArc *)[OFApplication sharedApplication].delegate; } + (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream mode: (OFString *)mode encoding: (OFStringEncoding)encoding { return [[[self alloc] initWithStream: stream mode: mode encoding: encoding] autorelease]; } - (instancetype)initWithStream: (OF_KINDOF(OFStream *))stream mode: (OFString *)mode encoding: (OFStringEncoding)encoding { self = [super init]; @try { _archive = [[OFLHAArchive alloc] initWithStream: stream mode: mode]; if (encoding != OFStringEncodingAutodetect) _archive.encoding = encoding; } @catch (id e) { [self release]; @throw e; } return self; |
︙ | ︙ | |||
129 130 131 132 133 134 135 | - (void)listFiles { OFLHAArchiveEntry *entry; while ((entry = [_archive nextEntry]) != nil) { void *pool = objc_autoreleasePoolPush(); | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | - (void)listFiles { OFLHAArchiveEntry *entry; while ((entry = [_archive nextEntry]) != nil) { void *pool = objc_autoreleasePoolPush(); [OFStdOut writeLine: entry.fileName]; if (app->_outputLevel >= 1) { OFString *date = [entry.date localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; OFString *compressedSize = [OFString stringWithFormat: @"%" PRIu32, entry.compressedSize]; OFString *uncompressedSize = [OFString stringWithFormat: @"%" PRIu32, entry.uncompressedSize]; OFString *CRC16 = [OFString stringWithFormat: @"%04" PRIX16, entry.CRC16]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_compressed_size", @"[" @" 'Compressed: '," @" [" @" {'size == 1': '1 byte'}," @" {'': '%[size] bytes'}" @" ]" @"]".objectByParsingJSON, @"size", compressedSize)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_uncompressed_size", @"[" @" 'Uncompressed: '," @" [" @" {'size == 1': '1 byte'}," @" {'': '%[size] bytes'}" @" ]" @"]".objectByParsingJSON, @"size", uncompressedSize)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_compression_method", @"Compression method: %[method]", @"method", entry.compressionMethod)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED(@"list_crc16", @"CRC16: %[crc16]", @"crc16", CRC16)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED(@"list_date", @"Date: %[date]", @"date", date)]; if (entry.mode != nil) { OFString *modeString = [OFString stringWithFormat: @"%ho", entry.mode.unsignedShortValue]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED(@"list_mode", @"Mode: %[mode]", @"mode", modeString)]; } if (entry.UID != nil) { [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED(@"list_uid", @"UID: %[uid]", @"uid", entry.UID)]; } if (entry.GID != nil) { [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED(@"list_gid", @"GID: %[gid]", @"gid", entry.GID)]; } if (entry.owner != nil) { [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_owner", @"Owner: %[owner]", @"owner", entry.owner)]; } if (entry.group != nil) { [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_group", @"Group: %[group]", @"group", entry.group)]; } if (app->_outputLevel >= 2) { OFString *headerLevel = [OFString stringWithFormat: @"%" PRIu8, entry.headerLevel]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_header_level", @"Header level: %[level]", @"level", headerLevel)]; if (entry.operatingSystemIdentifier != '\0') { OFString *OSID = [OFString stringWithFormat: @"%c", entry.operatingSystemIdentifier]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_osid", @"Operating system identifier: " "%[osid]", @"osid", OSID)]; } if (entry.modificationDate != nil) { OFString *modificationDate = entry.modificationDate.description; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_modification_date", @"Modification date: %[date]", @"date", modificationDate)]; } } if (app->_outputLevel >= 3) { OFString *extensions = indent(entry.extensions.description); [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_extensions", @"Extensions: %[extensions]", @"extensions", extensions)]; } } objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
290 291 292 293 294 295 296 | if (!all && ![files containsObject: fileName]) continue; [missing removeObject: fileName]; outFileName = [app safeLocalPathForPath: fileName]; if (outFileName == nil) { | | | | | | < | < | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | if (!all && ![files containsObject: fileName]) continue; [missing removeObject: fileName]; outFileName = [app safeLocalPathForPath: fileName]; if (outFileName == nil) { [OFStdErr writeLine: OF_LOCALIZED( @"refusing_to_extract_file", @"Refusing to extract %[file]!", @"file", fileName)]; app->_exitStatus = 1; goto outer_loop_end; } if (app->_outputLevel >= 0) [OFStdOut writeString: OF_LOCALIZED(@"extracting_file", @"Extracting %[file]...", @"file", fileName)]; if ([fileName hasSuffix: @"/"]) { [fileManager createDirectoryAtPath: outFileName createParents: true]; setPermissions(outFileName, entry); setModificationDate(outFileName, entry); if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"extracting_file_done", @"Extracting %[file]... done", @"file", fileName)]; } goto outer_loop_end; } directory = outFileName.stringByDeletingLastPathComponent; if (![fileManager directoryExistsAtPath: directory]) [fileManager createDirectoryAtPath: directory createParents: true]; if (![app shouldExtractFile: fileName outFileName: outFileName]) goto outer_loop_end; stream = [_archive streamForReadingCurrentEntry]; output = [OFFile fileWithPath: outFileName mode: @"w"]; setPermissions(outFileName, entry); while (!stream.atEndOfStream) { ssize_t length = [app copyBlockFromStream: stream toStream: output fileName: fileName]; |
︙ | ︙ | |||
356 357 358 359 360 361 362 | if (app->_outputLevel >= 0 && percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; | | | | | | | | | | | | | | | | | | | | > > > > > | | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 | if (app->_outputLevel >= 0 && percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; [OFStdOut writeString: @"\r"]; [OFStdOut writeString: OF_LOCALIZED( @"extracting_file_percent", @"Extracting %[file]... %[percent]%", @"file", fileName, @"percent", percentString)]; } } [output close]; setModificationDate(outFileName, entry); if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"extracting_file_done", @"Extracting %[file]... done", @"file", fileName)]; } outer_loop_end: objc_autoreleasePoolPop(pool); } if (missing.count > 0) { for (OFString *file in missing) [OFStdErr writeLine: OF_LOCALIZED( @"file_not_in_archive", @"File %[file] is not in the archive!", @"file", file)]; app->_exitStatus = 1; } } - (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files_ { OFMutableSet *files; OFLHAArchiveEntry *entry; if (files_.count < 1) { [OFStdErr writeLine: OF_LOCALIZED(@"print_no_file_specified", @"Need one or more files to print!")]; app->_exitStatus = 1; return; } files = [OFMutableSet setWithArray: files_]; while ((entry = [_archive nextEntry]) != nil) { OFString *fileName = entry.fileName; OFStream *stream; if (![files containsObject: fileName]) continue; stream = [_archive streamForReadingCurrentEntry]; while (!stream.atEndOfStream) { ssize_t length = [app copyBlockFromStream: stream toStream: OFStdOut fileName: fileName]; if (length < 0) { app->_exitStatus = 1; return; } } [files removeObject: fileName]; [stream close]; if (files.count == 0) break; } for (OFString *file in files) { [OFStdErr writeLine: OF_LOCALIZED(@"file_not_in_archive", @"File %[file] is not in the archive!", @"file", file)]; app->_exitStatus = 1; } } - (void)addFiles: (OFArray OF_GENERIC(OFString *) *)files { OFFileManager *fileManager = [OFFileManager defaultManager]; if (files.count < 1) { [OFStdErr writeLine: OF_LOCALIZED(@"add_no_file_specified", @"Need one or more files to add!")]; app->_exitStatus = 1; return; } for (OFString *fileName in files) { void *pool = objc_autoreleasePoolPush(); OFFileAttributes attributes; OFFileAttributeType type; OFMutableLHAArchiveEntry *entry; OFStream *output; if (app->_outputLevel >= 0) [OFStdOut writeString: OF_LOCALIZED(@"adding_file", @"Adding %[file]...", @"file", fileName)]; attributes = [fileManager attributesOfItemAtPath: fileName]; type = attributes.fileType; entry = [OFMutableLHAArchiveEntry entryWithFileName: fileName]; #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS entry.mode = [OFNumber numberWithUnsignedLong: attributes.filePOSIXPermissions]; #endif entry.date = attributes.fileModificationDate; #ifdef OF_FILE_MANAGER_SUPPORTS_OWNER entry.UID = [OFNumber numberWithUnsignedLong: attributes.fileOwnerAccountID]; entry.GID = [OFNumber numberWithUnsignedLong: attributes.fileGroupOwnerAccountID]; entry.owner = attributes.fileOwnerAccountName; entry.group = attributes.fileGroupOwnerAccountName; #endif if ([type isEqual: OFFileTypeDirectory]) { entry.compressionMethod = @"-lhd-"; if (![entry.fileName hasSuffix: @"/"]) entry.fileName = [entry.fileName stringByAppendingString: @"/"]; } output = [_archive streamForWritingEntry: entry]; if ([type isEqual: OFFileTypeRegular]) { unsigned long long written = 0; unsigned long long size = attributes.fileSize; int8_t percent = -1, newPercent; OFFile *input = [OFFile fileWithPath: fileName mode: @"r"]; |
︙ | ︙ | |||
518 519 520 521 522 523 524 | percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; | | | | | | 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; [OFStdOut writeString: @"\r"]; [OFStdOut writeString: OF_LOCALIZED( @"adding_file_percent", @"Adding %[file]... %[percent]%", @"file", fileName, @"percent", percentString)]; } } } if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"adding_file_done", @"Adding %[file]... done", @"file", fileName)]; } [output close]; |
︙ | ︙ |
Modified utils/ofarc/OFArc.h from [0119985fc9] to [926be48eea].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
37 38 39 40 41 42 43 | OFString *_archivePath; int _exitStatus; } - (id <Archive>)openArchiveWithPath: (OFString *)path type: (OFString *)type mode: (char)mode | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | OFString *_archivePath; int _exitStatus; } - (id <Archive>)openArchiveWithPath: (OFString *)path type: (OFString *)type mode: (char)mode encoding: (OFStringEncoding)encoding; - (bool)shouldExtractFile: (OFString *)fileName outFileName: (OFString *)outFileName; - (ssize_t)copyBlockFromStream: (OFStream *)input toStream: (OFStream *)output fileName: (OFString *)fileName; - (nullable OFString *)safeLocalPathForPath: (OFString *)path; @end OF_ASSUME_NONNULL_END |
Modified utils/ofarc/OFArc.m from [f2fa0ce091] to [6ddf1e5e68].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
40 41 42 43 44 45 46 | #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFOpenItemFailedException.h" #import "OFReadFailedException.h" #import "OFSeekFailedException.h" #import "OFWriteFailedException.h" | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #import "OFInvalidFormatException.h" #import "OFNotImplementedException.h" #import "OFOpenItemFailedException.h" #import "OFReadFailedException.h" #import "OFSeekFailedException.h" #import "OFWriteFailedException.h" #define bufferSize 4096 OF_APPLICATION_DELEGATE(OFArc) static void help(OFStream *stream, bool full, int status) { [stream writeLine: OF_LOCALIZED(@"usage", |
︙ | ︙ | |||
79 80 81 82 83 84 85 | @" -x --extract Extract files")]; } [OFApplication terminateWithStatus: status]; } static void | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > | | | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | @" -x --extract Extract files")]; } [OFApplication terminateWithStatus: status]; } static void mutuallyExclusiveError(OFUnichar shortOption1, OFString *longOption1, OFUnichar shortOption2, OFString *longOption2) { OFString *shortOption1Str = [OFString stringWithFormat: @"%C", shortOption1]; OFString *shortOption2Str = [OFString stringWithFormat: @"%C", shortOption2]; [OFStdErr writeLine: OF_LOCALIZED(@"2_options_mutually_exclusive", @"Error: -%[shortopt1] / --%[longopt1] and " @"-%[shortopt2] / --%[longopt2] " @"are mutually exclusive!", @"shortopt1", shortOption1Str, @"longopt1", longOption1, @"shortopt2", shortOption2Str, @"longopt2", longOption2)]; [OFApplication terminateWithStatus: 1]; } static void mutuallyExclusiveError5(OFUnichar shortOption1, OFString *longOption1, OFUnichar shortOption2, OFString *longOption2, OFUnichar shortOption3, OFString *longOption3, OFUnichar shortOption4, OFString *longOption4, OFUnichar shortOption5, OFString *longOption5) { OFString *shortOption1Str = [OFString stringWithFormat: @"%C", shortOption1]; OFString *shortOption2Str = [OFString stringWithFormat: @"%C", shortOption2]; OFString *shortOption3Str = [OFString stringWithFormat: @"%C", shortOption3]; OFString *shortOption4Str = [OFString stringWithFormat: @"%C", shortOption4]; OFString *shortOption5Str = [OFString stringWithFormat: @"%C", shortOption5]; [OFStdErr writeLine: OF_LOCALIZED(@"5_options_mutually_exclusive", @"Error: -%[shortopt1] / --%[longopt1], " @"-%[shortopt2] / --%[longopt2], -%[shortopt3] / --%[longopt3], " @"-%[shortopt4] / --%[longopt4] and\n" @" -%[shortopt5] / --%[longopt5] are mutually exclusive!", @"shortopt1", shortOption1Str, @"longopt1", longOption1, @"shortopt2", shortOption2Str, @"longopt2", longOption2, @"shortopt3", shortOption3Str, @"longopt3", longOption3, @"shortopt4", shortOption4Str, @"longopt4", longOption4, @"shortopt5", shortOption5Str, @"longopt5", longOption5)]; [OFApplication terminateWithStatus: 1]; } static void writingNotSupported(OFString *type) { [OFStdErr writeLine: OF_LOCALIZED( @"writing_not_supported", @"Writing archives of type %[type] is not (yet) supported!", @"type", type)]; } static void addFiles(id <Archive> archive, OFArray OF_GENERIC(OFString *) *files) { OFMutableArray *expandedFiles = [OFMutableArray arrayWithCapacity: files.count]; OFFileManager *fileManager = [OFFileManager defaultManager]; for (OFString *file in files) { OFFileAttributes attributes = [fileManager attributesOfItemAtPath: file]; if ([attributes.fileType isEqual: OFFileTypeDirectory]) [expandedFiles addObjectsFromArray: [fileManager subpathsOfDirectoryAtPath: file]]; else [expandedFiles addObject: file]; } [archive addFiles: expandedFiles]; } @implementation OFArc - (void)applicationDidFinishLaunching { OFString *outputDir, *encodingString, *type; const OFOptionsParserOption options[] = { { 'a', @"append", 0, NULL, NULL }, { 'c', @"create", 0, NULL, NULL }, { 'C', @"directory", 1, NULL, &outputDir }, { 'E', @"encoding", 1, NULL, &encodingString }, { 'f', @"force", 0, NULL, NULL }, { 'h', @"help", 0, NULL, NULL }, { 'l', @"list", 0, NULL, NULL }, { 'n', @"no-clobber", 0, NULL, NULL }, { 'p', @"print", 0, NULL, NULL }, { 'q', @"quiet", 0, NULL, NULL }, { 't', @"type", 1, NULL, &type }, { 'v', @"verbose", 0, NULL, NULL }, { 'x', @"extract", 0, NULL, NULL }, { '\0', nil, 0, NULL, NULL } }; OFUnichar option, mode = '\0'; OFStringEncoding encoding = OFStringEncodingAutodetect; OFOptionsParser *optionsParser; OFArray OF_GENERIC(OFString *) *remainingArguments, *files; id <Archive> archive; #ifdef OF_HAVE_SANDBOX OFSandbox *sandbox = [OFSandbox sandbox]; sandbox.allowsStdIO = true; sandbox.allowsReadingFiles = true; sandbox.allowsWritingFiles = true; sandbox.allowsCreatingFiles = true; sandbox.allowsChangingFileAttributes = true; sandbox.allowsUserDatabaseReading = true; /* Dropped after parsing options */ sandbox.allowsUnveil = true; [OFApplication of_activateSandbox: sandbox]; #endif #ifndef OF_AMIGAOS [OFLocale addLanguageDirectory: @LANGUAGE_DIR]; #else [OFLocale addLanguageDirectory: @"PROGDIR:/share/ofarc/lang"]; #endif |
︙ | ︙ | |||
236 237 238 239 240 241 242 | 'l', @"list", 'p', @"print", 'x', @"extract"); mode = option; break; case 'h': | | | | | | | | | | | | < | | | | | | | | | | < | | > > > > | < | | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | 'l', @"list", 'p', @"print", 'x', @"extract"); mode = option; break; case 'h': help(OFStdOut, true, 0); break; case '=': [OFStdErr writeLine: OF_LOCALIZED( @"option_takes_no_argument", @"%[prog]: Option --%[opt] takes no argument", @"prog", [OFApplication programName], @"opt", optionsParser.lastLongOption)]; [OFApplication terminateWithStatus: 1]; break; case ':': if (optionsParser.lastLongOption != nil) [OFStdErr writeLine: OF_LOCALIZED( @"long_option_requires_argument", @"%[prog]: Option --%[opt] requires an " @"argument", @"prog", [OFApplication programName], @"opt", optionsParser.lastLongOption)]; else { OFString *optStr = [OFString stringWithFormat: @"%C", optionsParser.lastOption]; [OFStdErr writeLine: OF_LOCALIZED( @"option_requires_argument", @"%[prog]: Option -%[opt] requires an " @"argument", @"prog", [OFApplication programName], @"opt", optStr)]; } [OFApplication terminateWithStatus: 1]; break; case '?': if (optionsParser.lastLongOption != nil) [OFStdErr writeLine: OF_LOCALIZED( @"unknown_long_option", @"%[prog]: Unknown option: --%[opt]", @"prog", [OFApplication programName], @"opt", optionsParser.lastLongOption)]; else { OFString *optStr = [OFString stringWithFormat: @"%C", optionsParser.lastOption]; [OFStdErr writeLine: OF_LOCALIZED( @"unknown_option", @"%[prog]: Unknown option: -%[opt]", @"prog", [OFApplication programName], @"opt", optStr)]; } [OFApplication terminateWithStatus: 1]; break; } } @try { if (encodingString != nil) encoding = OFStringEncodingParseName(encodingString); } @catch (OFInvalidArgumentException *e) { [OFStdErr writeLine: OF_LOCALIZED( @"invalid_encoding", @"%[prog]: Invalid encoding: %[encoding]", @"prog", [OFApplication programName], @"encoding", encodingString)]; [OFApplication terminateWithStatus: 1]; } remainingArguments = optionsParser.remainingArguments; switch (mode) { case 'a': case 'c': if (remainingArguments.count < 1) help(OFStdErr, false, 1); files = [remainingArguments objectsInRange: OFRangeMake(1, remainingArguments.count - 1)]; #ifdef OF_HAVE_SANDBOX if (![remainingArguments.firstObject isEqual: @"-"]) [sandbox unveilPath: remainingArguments.firstObject permissions: (mode == 'a' ? @"rwc" : @"wc")]; for (OFString *path in files) [sandbox unveilPath: path permissions: @"r"]; sandbox.allowsUnveil = false; [OFApplication of_activateSandbox: sandbox]; #endif archive = [self openArchiveWithPath: remainingArguments.firstObject type: type mode: mode encoding: encoding]; addFiles(archive, files); break; case 'l': if (remainingArguments.count != 1) help(OFStdErr, false, 1); #ifdef OF_HAVE_SANDBOX if (![remainingArguments.firstObject isEqual: @"-"]) [sandbox unveilPath: remainingArguments.firstObject permissions: @"r"]; sandbox.allowsUnveil = false; [OFApplication of_activateSandbox: sandbox]; #endif archive = [self openArchiveWithPath: remainingArguments.firstObject type: type mode: mode encoding: encoding]; [archive listFiles]; break; case 'p': if (remainingArguments.count < 1) help(OFStdErr, false, 1); #ifdef OF_HAVE_SANDBOX if (![remainingArguments.firstObject isEqual: @"-"]) [sandbox unveilPath: remainingArguments.firstObject permissions: @"r"]; sandbox.allowsUnveil = false; [OFApplication of_activateSandbox: sandbox]; #endif files = [remainingArguments objectsInRange: OFRangeMake(1, remainingArguments.count - 1)]; archive = [self openArchiveWithPath: remainingArguments.firstObject type: type mode: mode encoding: encoding]; [archive printFiles: files]; break; case 'x': if (remainingArguments.count < 1) help(OFStdErr, false, 1); files = [remainingArguments objectsInRange: OFRangeMake(1, remainingArguments.count - 1)]; #ifdef OF_HAVE_SANDBOX if (![remainingArguments.firstObject isEqual: @"-"]) [sandbox unveilPath: remainingArguments.firstObject permissions: @"r"]; if (files.count > 0) for (OFString *path in files) [sandbox unveilPath: path permissions: @"wc"]; else { OFString *path = outputDir; if (path == nil) path = [[OFFileManager defaultManager] currentDirectoryPath]; /* We need 'r' to change the directory to it. */ [sandbox unveilPath: path permissions: @"rwc"]; } sandbox.allowsUnveil = false; [OFApplication of_activateSandbox: sandbox]; #endif archive = [self openArchiveWithPath: remainingArguments.firstObject type: type mode: mode encoding: encoding]; |
︙ | ︙ | |||
433 434 435 436 437 438 439 | @try { [archive extractFiles: files]; } @catch (OFCreateDirectoryFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; | | | | | | | | 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 | @try { [archive extractFiles: files]; } @catch (OFCreateDirectoryFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; [OFStdErr writeString: @"\r"]; [OFStdErr writeLine: OF_LOCALIZED( @"failed_to_create_directory", @"Failed to create directory %[dir]: %[error]", @"dir", e.URL.fileSystemRepresentation, @"error", error)]; _exitStatus = 1; } @catch (OFOpenItemFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; [OFStdErr writeString: @"\r"]; [OFStdErr writeLine: OF_LOCALIZED( @"failed_to_open_file", @"Failed to open file %[file]: %[error]", @"file", e.path, @"error", error)]; _exitStatus = 1; } break; default: help(OFStdErr, true, 1); break; } [OFApplication terminateWithStatus: _exitStatus]; } - (id <Archive>)openArchiveWithPath: (OFString *)path type: (OFString *)type mode: (char)mode encoding: (OFStringEncoding)encoding { OFString *modeString, *fileModeString; OFStream *file = nil; id <Archive> archive = nil; [_archivePath release]; _archivePath = [path copy]; |
︙ | ︙ | |||
498 499 500 501 502 503 504 | @throw [OFInvalidArgumentException exception]; } if ([path isEqual: @"-"]) { switch (mode) { case 'a': case 'c': | | | | < | | | 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 | @throw [OFInvalidArgumentException exception]; } if ([path isEqual: @"-"]) { switch (mode) { case 'a': case 'c': file = OFStdOut; break; case 'l': case 'p': case 'x': file = OFStdIn; break; default: @throw [OFInvalidArgumentException exception]; } } else { @try { file = [OFFile fileWithPath: path mode: fileModeString]; } @catch (OFOpenItemFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; [OFStdErr writeString: @"\r"]; [OFStdErr writeLine: OF_LOCALIZED( @"failed_to_open_file", @"Failed to open file %[file]: %[error]", @"file", e.path, @"error", error)]; [OFApplication terminateWithStatus: 1]; } } |
︙ | ︙ | |||
566 567 568 569 570 571 572 | mode: modeString encoding: encoding]; } else if ([type isEqual: @"zip"]) archive = [ZIPArchive archiveWithStream: file mode: modeString encoding: encoding]; else { | | | | | | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 | mode: modeString encoding: encoding]; } else if ([type isEqual: @"zip"]) archive = [ZIPArchive archiveWithStream: file mode: modeString encoding: encoding]; else { [OFStdErr writeLine: OF_LOCALIZED( @"unknown_archive_type", @"Unknown archive type: %[type]", @"type", type)]; goto error; } } @catch (OFNotImplementedException *e) { if ((mode == 'a' || mode == 'c') && sel_isEqual(e.selector, @selector(initWithStream:mode:))) { writingNotSupported(type); goto error; } @throw e; } @catch (OFReadFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; [OFStdErr writeLine: OF_LOCALIZED(@"failed_to_read_file", @"Failed to read file %[file]: %[error]", @"file", path, @"error", error)]; goto error; } @catch (OFSeekFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; [OFStdErr writeLine: OF_LOCALIZED(@"failed_to_seek_in_file", @"Failed to seek in file %[file]: %[error]", @"file", path, @"error", error)]; goto error; } @catch (OFInvalidFormatException *e) { [OFStdErr writeLine: OF_LOCALIZED( @"file_is_not_a_valid_archive", @"File %[file] is not a valid archive!", @"file", path)]; goto error; } if ((mode == 'a' || mode == 'c') && |
︙ | ︙ | |||
633 634 635 636 637 638 639 | if (_overwrite == 1 || ![[OFFileManager defaultManager] fileExistsAtPath: outFileName]) return true; if (_overwrite == -1) { if (_outputLevel >= 0) { | | | | | | | | | | | | < | | | < | | | 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 | if (_overwrite == 1 || ![[OFFileManager defaultManager] fileExistsAtPath: outFileName]) return true; if (_overwrite == -1) { if (_outputLevel >= 0) { [OFStdOut writeString: @" "]; [OFStdOut writeLine: OF_LOCALIZED(@"file_skipped", @"skipped")]; } return false; } do { [OFStdErr writeString: @"\r"]; [OFStdErr writeString: OF_LOCALIZED(@"ask_overwrite", @"Overwrite %[file]? [ynAN?]", @"file", fileName)]; [OFStdErr writeString: @" "]; line = [OFStdIn readLine]; if ([line isEqual: @"?"]) [OFStdErr writeLine: OF_LOCALIZED( @"ask_overwrite_help", @" y: yes\n" @" n: no\n" @" A: always\n" @" N: never")]; } while (![line isEqual: @"y"] && ![line isEqual: @"n"] && ![line isEqual: @"N"] && ![line isEqual: @"A"]); if ([line isEqual: @"A"]) _overwrite = 1; else if ([line isEqual: @"N"]) _overwrite = -1; if ([line isEqual: @"n"] || [line isEqual: @"N"]) { if (_outputLevel >= 0) [OFStdOut writeLine: OF_LOCALIZED(@"skipping_file", @"Skipping %[file]...", @"file", fileName)]; return false; } if (_outputLevel >= 0) [OFStdOut writeString: OF_LOCALIZED(@"extracting_file", @"Extracting %[file]...", @"file", fileName)]; return true; } - (ssize_t)copyBlockFromStream: (OFStream *)input toStream: (OFStream *)output fileName: (OFString *)fileName { char buffer[bufferSize]; size_t length; @try { length = [input readIntoBuffer: buffer length: bufferSize]; } @catch (OFReadFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; [OFStdOut writeString: @"\r"]; [OFStdErr writeLine: OF_LOCALIZED(@"failed_to_read_file", @"Failed to read file %[file]: %[error]", @"file", fileName, @"error", error)]; return -1; } @try { [output writeBuffer: buffer length: length]; } @catch (OFWriteFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; [OFStdOut writeString: @"\r"]; [OFStdErr writeLine: OF_LOCALIZED(@"failed_to_write_file", @"Failed to write file %[file]: %[error]", @"file", fileName, @"error", error)]; return -1; } return length; |
︙ | ︙ |
Modified utils/ofarc/TarArchive.h from [55ced9e062] to [5ee57845a6].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified utils/ofarc/TarArchive.m from [3ca97fcaef] to [52a1c25d9d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
32 33 34 35 36 37 38 | static OFArc *app; static void setPermissions(OFString *path, OFTarArchiveEntry *entry) { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS OFNumber *mode = [OFNumber numberWithUnsignedShort: entry.mode & 0777]; | | | | | | | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | static OFArc *app; static void setPermissions(OFString *path, OFTarArchiveEntry *entry) { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS OFNumber *mode = [OFNumber numberWithUnsignedShort: entry.mode & 0777]; OFFileAttributes attributes = [OFDictionary dictionaryWithObject: mode forKey: OFFilePOSIXPermissions]; [[OFFileManager defaultManager] setAttributes: attributes ofItemAtPath: path]; #endif } static void setModificationDate(OFString *path, OFTarArchiveEntry *entry) { OFDate *modificationDate = entry.modificationDate; OFFileAttributes attributes; if (modificationDate == nil) return; attributes = [OFDictionary dictionaryWithObject: modificationDate forKey: OFFileModificationDate]; [[OFFileManager defaultManager] setAttributes: attributes ofItemAtPath: path]; } @implementation TarArchive + (void)initialize { if (self == [TarArchive class]) app = (OFArc *)[OFApplication sharedApplication].delegate; } + (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream mode: (OFString *)mode encoding: (OFStringEncoding)encoding { return [[[self alloc] initWithStream: stream mode: mode encoding: encoding] autorelease]; } - (instancetype)initWithStream: (OF_KINDOF(OFStream *))stream mode: (OFString *)mode encoding: (OFStringEncoding)encoding { self = [super init]; @try { _archive = [[OFTarArchive alloc] initWithStream: stream mode: mode]; if (encoding != OFStringEncodingAutodetect) _archive.encoding = encoding; } @catch (id e) { [self release]; @throw e; } return self; |
︙ | ︙ | |||
107 108 109 110 111 112 113 | - (void)listFiles { OFTarArchiveEntry *entry; while ((entry = [_archive nextEntry]) != nil) { void *pool = objc_autoreleasePoolPush(); | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | - (void)listFiles { OFTarArchiveEntry *entry; while ((entry = [_archive nextEntry]) != nil) { void *pool = objc_autoreleasePoolPush(); [OFStdOut writeLine: entry.fileName]; if (app->_outputLevel >= 1) { OFString *date = [entry.modificationDate localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; OFString *size = [OFString stringWithFormat: @"%" PRIu64, entry.size]; OFString *mode = [OFString stringWithFormat: @"%06o", entry.mode]; OFString *UID = [OFString stringWithFormat: @"%u", entry.UID]; OFString *GID = [OFString stringWithFormat: @"%u", entry.GID]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED(@"list_size", @"[" @" 'Size: '," @" [" @" {'size == 1': '1 byte'}," @" {'': '%[size] bytes'}" @" ]" @"]".objectByParsingJSON, @"size", size)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED(@"list_mode", @"Mode: %[mode]", @"mode", mode)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED(@"list_uid", @"UID: %[uid]", @"uid", UID)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED(@"list_gid", @"GID: %[gid]", @"gid", GID)]; if (entry.owner != nil) { [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_owner", @"Owner: %[owner]", @"owner", entry.owner)]; } if (entry.group != nil) { [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_group", @"Group: %[group]", @"group", entry.group)]; } [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_modification_date", @"Modification date: %[date]", @"date", date)]; } if (app->_outputLevel >= 2) { [OFStdOut writeString: @"\t"]; switch (entry.type) { case OFTarArchiveEntryTypeFile: [OFStdOut writeLine: OF_LOCALIZED( @"list_type_normal", @"Type: Normal file")]; break; case OFTarArchiveEntryTypeLink: [OFStdOut writeLine: OF_LOCALIZED( @"list_type_hardlink", @"Type: Hard link")]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_link_target", @"Target file name: %[target]", @"target", entry.targetFileName)]; break; case OFTarArchiveEntryTypeSymlink: [OFStdOut writeLine: OF_LOCALIZED( @"list_type_symlink", @"Type: Symbolic link")]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_link_target", @"Target file name: %[target]", @"target", entry.targetFileName)]; break; case OFTarArchiveEntryTypeCharacterDevice: { OFString *majorString = [OFString stringWithFormat: @"%d", entry.deviceMajor]; OFString *minorString = [OFString stringWithFormat: @"%d", entry.deviceMinor]; [OFStdOut writeLine: OF_LOCALIZED( @"list_type_character_device", @"Type: Character device")]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_device_major", @"Device major: %[major]", @"major", majorString)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_device_minor", @"Device minor: %[minor]", @"minor", minorString)]; break; } case OFTarArchiveEntryTypeBlockDevice: { OFString *majorString = [OFString stringWithFormat: @"%d", entry.deviceMajor]; OFString *minorString = [OFString stringWithFormat: @"%d", entry.deviceMinor]; [OFStdOut writeLine: OF_LOCALIZED( @"list_type_block_device", @"Type: Block device")]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_device_major", @"Device major: %[major]", @"major", majorString)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_device_minor", @"Device minor: %[minor]", @"minor", minorString)]; break; } case OFTarArchiveEntryTypeDirectory: [OFStdOut writeLine: OF_LOCALIZED( @"list_type_directory", @"Type: Directory")]; break; case OFTarArchiveEntryTypeFIFO: [OFStdOut writeLine: OF_LOCALIZED( @"list_type_fifo", @"Type: FIFO")]; break; case OFTarArchiveEntryTypeContiguousFile: [OFStdOut writeLine: OF_LOCALIZED( @"list_type_contiguous_file", @"Type: Contiguous file")]; break; default: [OFStdOut writeLine: OF_LOCALIZED( @"list_type_unknown", @"Type: Unknown")]; break; } } objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
275 276 277 278 279 280 281 | OFMutableSet OF_GENERIC(OFString *) *missing = [OFMutableSet setWithArray: files]; OFTarArchiveEntry *entry; while ((entry = [_archive nextEntry]) != nil) { void *pool = objc_autoreleasePoolPush(); OFString *fileName = entry.fileName; | | | | | | | | | | | | < | < | 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | OFMutableSet OF_GENERIC(OFString *) *missing = [OFMutableSet setWithArray: files]; OFTarArchiveEntry *entry; while ((entry = [_archive nextEntry]) != nil) { void *pool = objc_autoreleasePoolPush(); OFString *fileName = entry.fileName; OFTarArchiveEntryType type = entry.type; OFString *outFileName, *directory; OFFile *output; OFStream *stream; uint64_t written = 0, size = entry.size; int8_t percent = -1, newPercent; if (!all && ![files containsObject: fileName]) continue; if (type != OFTarArchiveEntryTypeFile && type != OFTarArchiveEntryTypeDirectory) { if (app->_outputLevel >= 0) [OFStdOut writeLine: OF_LOCALIZED( @"skipping_file", @"Skipping %[file]...", @"file", fileName)]; continue; } [missing removeObject: fileName]; outFileName = [app safeLocalPathForPath: fileName]; if (outFileName == nil) { [OFStdErr writeLine: OF_LOCALIZED( @"refusing_to_extract_file", @"Refusing to extract %[file]!", @"file", fileName)]; app->_exitStatus = 1; goto outer_loop_end; } if (app->_outputLevel >= 0) [OFStdOut writeString: OF_LOCALIZED(@"extracting_file", @"Extracting %[file]...", @"file", fileName)]; if (type == OFTarArchiveEntryTypeDirectory || (type == OFTarArchiveEntryTypeFile && [fileName hasSuffix: @"/"])) { [fileManager createDirectoryAtPath: outFileName createParents: true]; setPermissions(outFileName, entry); setModificationDate(outFileName, entry); if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"extracting_file_done", @"Extracting %[file]... done", @"file", fileName)]; } goto outer_loop_end; } directory = outFileName.stringByDeletingLastPathComponent; if (![fileManager directoryExistsAtPath: directory]) [fileManager createDirectoryAtPath: directory createParents: true]; if (![app shouldExtractFile: fileName outFileName: outFileName]) goto outer_loop_end; stream = [_archive streamForReadingCurrentEntry]; output = [OFFile fileWithPath: outFileName mode: @"w"]; setPermissions(outFileName, entry); while (!stream.atEndOfStream) { ssize_t length = [app copyBlockFromStream: stream toStream: output fileName: fileName]; |
︙ | ︙ | |||
367 368 369 370 371 372 373 | if (app->_outputLevel >= 0 && percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; | | | | | | | | | | | | | | | | | | | | | | | | | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 | if (app->_outputLevel >= 0 && percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; [OFStdOut writeString: @"\r"]; [OFStdOut writeString: OF_LOCALIZED( @"extracting_file_percent", @"Extracting %[file]... %[percent]%", @"file", fileName, @"percent", percentString)]; } } [output close]; setModificationDate(outFileName, entry); if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"extracting_file_done", @"Extracting %[file]... done", @"file", fileName)]; } outer_loop_end: objc_autoreleasePoolPop(pool); } if (missing.count > 0) { for (OFString *file in missing) [OFStdErr writeLine: OF_LOCALIZED( @"file_not_in_archive", @"File %[file] is not in the archive!", @"file", file)]; app->_exitStatus = 1; } } - (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files_ { OFMutableSet *files; OFTarArchiveEntry *entry; if (files_.count < 1) { [OFStdErr writeLine: OF_LOCALIZED(@"print_no_file_specified", @"Need one or more files to print!")]; app->_exitStatus = 1; return; } files = [OFMutableSet setWithArray: files_]; while ((entry = [_archive nextEntry]) != nil) { OFString *fileName = entry.fileName; OFStream *stream; if (![files containsObject: fileName]) continue; stream = [_archive streamForReadingCurrentEntry]; while (!stream.atEndOfStream) { ssize_t length = [app copyBlockFromStream: stream toStream: OFStdOut fileName: fileName]; if (length < 0) { app->_exitStatus = 1; return; } } [files removeObject: fileName]; [stream close]; if (files.count == 0) break; } for (OFString *file in files) { [OFStdErr writeLine: OF_LOCALIZED(@"file_not_in_archive", @"File %[file] is not in the archive!", @"file", file)]; app->_exitStatus = 1; } } - (void)addFiles: (OFArray OF_GENERIC(OFString *) *)files { OFFileManager *fileManager = [OFFileManager defaultManager]; if (files.count < 1) { [OFStdErr writeLine: OF_LOCALIZED(@"add_no_file_specified", @"Need one or more files to add!")]; app->_exitStatus = 1; return; } for (OFString *fileName in files) { void *pool = objc_autoreleasePoolPush(); OFFileAttributes attributes; OFFileAttributeType type; OFMutableTarArchiveEntry *entry; OFStream *output; if (app->_outputLevel >= 0) [OFStdOut writeString: OF_LOCALIZED(@"adding_file", @"Adding %[file]...", @"file", fileName)]; attributes = [fileManager attributesOfItemAtPath: fileName]; type = attributes.fileType; entry = [OFMutableTarArchiveEntry entryWithFileName: fileName]; #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS entry.mode = attributes.filePOSIXPermissions; #endif entry.size = attributes.fileSize; entry.modificationDate = attributes.fileModificationDate; #ifdef OF_FILE_MANAGER_SUPPORTS_OWNER entry.UID = attributes.fileOwnerAccountID; entry.GID = attributes.fileGroupOwnerAccountID; entry.owner = attributes.fileOwnerAccountName; entry.group = attributes.fileGroupOwnerAccountName; #endif if ([type isEqual: OFFileTypeRegular]) entry.type = OFTarArchiveEntryTypeFile; else if ([type isEqual: OFFileTypeDirectory]) { entry.type = OFTarArchiveEntryTypeDirectory; entry.size = 0; } else if ([type isEqual: OFFileTypeSymbolicLink]) { entry.type = OFTarArchiveEntryTypeSymlink; entry.targetFileName = attributes.fileSymbolicLinkDestination; entry.size = 0; } [entry makeImmutable]; output = [_archive streamForWritingEntry: entry]; if (entry.type == OFTarArchiveEntryTypeFile) { uint64_t written = 0, size = entry.size; int8_t percent = -1, newPercent; OFFile *input = [OFFile fileWithPath: fileName mode: @"r"]; while (!input.atEndOfStream) { |
︙ | ︙ | |||
537 538 539 540 541 542 543 | percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; | | | | | | 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 | percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; [OFStdOut writeString: @"\r"]; [OFStdOut writeString: OF_LOCALIZED( @"adding_file_percent", @"Adding %[file]... %[percent]%", @"file", fileName, @"percent", percentString)]; } } } if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"adding_file_done", @"Adding %[file]... done", @"file", fileName)]; } [output close]; |
︙ | ︙ |
Modified utils/ofarc/ZIPArchive.h from [14f409a4c2] to [8566715690].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ |
Modified utils/ofarc/ZIPArchive.m from [4b4d3715d0] to [0cdfabe7b0].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
39 40 41 42 43 44 45 | static OFArc *app; static void setPermissions(OFString *path, OFZIPArchiveEntry *entry) { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS if ((entry.versionMadeBy >> 8) == | | < < | | | | | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | static OFArc *app; static void setPermissions(OFString *path, OFZIPArchiveEntry *entry) { #ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS if ((entry.versionMadeBy >> 8) == OFZIPArchiveEntryAttributeCompatibilityUNIX) { OFNumber *mode = [OFNumber numberWithUnsignedShort: (entry.versionSpecificAttributes >> 16) & 0777]; OFFileAttributes attributes = [OFDictionary dictionaryWithObject: mode forKey: OFFilePOSIXPermissions]; [[OFFileManager defaultManager] setAttributes: attributes ofItemAtPath: path]; } #endif } static void setModificationDate(OFString *path, OFZIPArchiveEntry *entry) { OFDate *modificationDate = entry.modificationDate; OFFileAttributes attributes; if (modificationDate == nil) return; attributes = [OFDictionary dictionaryWithObject: modificationDate forKey: OFFileModificationDate]; [[OFFileManager defaultManager] setAttributes: attributes ofItemAtPath: path]; } @implementation ZIPArchive + (void)initialize { if (self == [ZIPArchive class]) app = (OFArc *)[OFApplication sharedApplication].delegate; } + (instancetype)archiveWithStream: (OF_KINDOF(OFStream *))stream mode: (OFString *)mode encoding: (OFStringEncoding)encoding { return [[[self alloc] initWithStream: stream mode: mode encoding: encoding] autorelease]; } - (instancetype)initWithStream: (OF_KINDOF(OFStream *))stream mode: (OFString *)mode encoding: (OFStringEncoding)encoding { self = [super init]; @try { _archive = [[OFZIPArchive alloc] initWithStream: stream mode: mode]; } @catch (id e) { |
︙ | ︙ | |||
115 116 117 118 119 120 121 | } - (void)listFiles { for (OFZIPArchiveEntry *entry in _archive.entries) { void *pool = objc_autoreleasePoolPush(); | | | | | | | | | | | | | > > | | | | | | | < | | | | | | | | | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | } - (void)listFiles { for (OFZIPArchiveEntry *entry in _archive.entries) { void *pool = objc_autoreleasePoolPush(); [OFStdOut writeLine: entry.fileName]; if (app->_outputLevel >= 1) { OFString *compressedSize = [OFString stringWithFormat: @"%" PRIu64, entry.compressedSize]; OFString *uncompressedSize = [OFString stringWithFormat: @"%" PRIu64, entry.uncompressedSize]; OFString *compressionMethod = OFZIPArchiveEntryCompressionMethodName( entry.compressionMethod); OFString *CRC32 = [OFString stringWithFormat: @"%08" PRIX32, entry.CRC32]; OFString *modificationDate = [entry.modificationDate localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_compressed_size", @"[" @" 'Compressed: '," @" [" @" {'size == 1': '1 byte'}," @" {'': '%[size] bytes'}" @" ]" @"]".objectByParsingJSON, @"size", compressedSize)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_uncompressed_size", @"[" @" 'Uncompressed: '," @" [" @" {'size == 1': '1 byte'}," @" {'': '%[size] bytes'}" @" ]" @"]".objectByParsingJSON, @"size", uncompressedSize)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_compression_method", @"Compression method: %[method]", @"method", compressionMethod)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED(@"list_crc32", @"CRC32: %[crc32]", @"crc32", CRC32)]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_modification_date", @"Modification date: %[date]", @"date", modificationDate)]; if (app->_outputLevel >= 2) { uint16_t versionMadeBy = entry.versionMadeBy; OFZIPArchiveEntryAttributeCompatibility UNIX = OFZIPArchiveEntryAttributeCompatibilityUNIX; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_version_made_by", @"Version made by: %[version]", @"version", OFZIPArchiveEntryVersionToString( versionMadeBy))]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_min_version_needed", @"Minimum version needed: %[version]", @"version", OFZIPArchiveEntryVersionToString( entry.minVersionNeeded))]; if ((versionMadeBy >> 8) == UNIX) { uint32_t mode = entry .versionSpecificAttributes >> 16; OFString *modeString = [OFString stringWithFormat: @"%06o", mode]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_mode", @"Mode: %[mode]", @"mode", modeString)]; } } if (app->_outputLevel >= 3) { OFString *GPBF = [OFString stringWithFormat: @"%04" PRIx16, entry.generalPurposeBitFlag]; [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_general_purpose_bit_flag", @"General purpose bit flag: %[gpbf]", @"gpbf", GPBF)]; if (entry.extraField != nil) { [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_extra_field", @"Extra field: %[extra]", @"extra", entry.extraField.description)]; } } if (entry.fileComment.length > 0) { [OFStdOut writeString: @"\t"]; [OFStdOut writeLine: OF_LOCALIZED( @"list_comment", @"Comment: %[comment]", @"comment", entry.fileComment)]; } } objc_autoreleasePoolPop(pool); |
︙ | ︙ | |||
257 258 259 260 261 262 263 | if (!all && ![files containsObject: fileName]) continue; [missing removeObject: fileName]; outFileName = [app safeLocalPathForPath: fileName]; if (outFileName == nil) { | | | | | | < | < | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | if (!all && ![files containsObject: fileName]) continue; [missing removeObject: fileName]; outFileName = [app safeLocalPathForPath: fileName]; if (outFileName == nil) { [OFStdErr writeLine: OF_LOCALIZED( @"refusing_to_extract_file", @"Refusing to extract %[file]!", @"file", fileName)]; app->_exitStatus = 1; goto outer_loop_end; } if (app->_outputLevel >= 0) [OFStdOut writeString: OF_LOCALIZED(@"extracting_file", @"Extracting %[file]...", @"file", fileName)]; if ([fileName hasSuffix: @"/"]) { [fileManager createDirectoryAtPath: outFileName createParents: true]; setPermissions(outFileName, entry); setModificationDate(outFileName, entry); if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"extracting_file_done", @"Extracting %[file]... done", @"file", fileName)]; } goto outer_loop_end; } directory = outFileName.stringByDeletingLastPathComponent; if (![fileManager directoryExistsAtPath: directory]) [fileManager createDirectoryAtPath: directory createParents: true]; if (![app shouldExtractFile: fileName outFileName: outFileName]) goto outer_loop_end; stream = [_archive streamForReadingFile: fileName]; output = [OFFile fileWithPath: outFileName mode: @"w"]; setPermissions(outFileName, entry); while (!stream.atEndOfStream) { ssize_t length = [app copyBlockFromStream: stream toStream: output fileName: fileName]; |
︙ | ︙ | |||
323 324 325 326 327 328 329 | if (app->_outputLevel >= 0 && percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; | | | | | | | | | | | | | | | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 | if (app->_outputLevel >= 0 && percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; [OFStdOut writeString: @"\r"]; [OFStdOut writeString: OF_LOCALIZED( @"extracting_file_percent", @"Extracting %[file]... %[percent]%", @"file", fileName, @"percent", percentString)]; } } [output close]; setModificationDate(outFileName, entry); if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"extracting_file_done", @"Extracting %[file]... done", @"file", fileName)]; } outer_loop_end: objc_autoreleasePoolPop(pool); } if (missing.count > 0) { for (OFString *file in missing) [OFStdErr writeLine: OF_LOCALIZED( @"file_not_in_archive", @"File %[file] is not in the archive!", @"file", file)]; app->_exitStatus = 1; } } - (void)printFiles: (OFArray OF_GENERIC(OFString *) *)files { OFStream *stream; if (files.count < 1) { [OFStdErr writeLine: OF_LOCALIZED(@"print_no_file_specified", @"Need one or more files to print!")]; app->_exitStatus = 1; return; } for (OFString *path in files) { @try { stream = [_archive streamForReadingFile: path]; } @catch (OFOpenItemFailedException *e) { if (e.errNo == ENOENT) { [OFStdErr writeLine: OF_LOCALIZED( @"file_not_in_archive", @"File %[file] is not in the archive!", @"file", e.path)]; app->_exitStatus = 1; continue; } @throw e; } while (!stream.atEndOfStream) { ssize_t length = [app copyBlockFromStream: stream toStream: OFStdOut fileName: path]; if (length < 0) { app->_exitStatus = 1; return; } } [stream close]; } } - (void)addFiles: (OFArray OF_GENERIC(OFString *) *)files { OFFileManager *fileManager = [OFFileManager defaultManager]; if (files.count < 1) { [OFStdErr writeLine: OF_LOCALIZED(@"add_no_file_specified", @"Need one or more files to add!")]; app->_exitStatus = 1; return; } for (OFString *localFileName in files) { void *pool = objc_autoreleasePoolPush(); OFArray OF_GENERIC (OFString *) *components; OFString *fileName; OFFileAttributes attributes; bool isDirectory = false; OFMutableZIPArchiveEntry *entry; unsigned long long size; OFStream *output; components = localFileName.pathComponents; fileName = [components componentsJoinedByString: @"/"]; attributes = [fileManager attributesOfItemAtPath: localFileName]; if ([attributes.fileType isEqual: OFFileTypeDirectory]) { isDirectory = true; fileName = [fileName stringByAppendingString: @"/"]; } if (app->_outputLevel >= 0) [OFStdOut writeString: OF_LOCALIZED(@"adding_file", @"Adding %[file]...", @"file", fileName)]; entry = [OFMutableZIPArchiveEntry entryWithFileName: fileName]; size = (isDirectory ? 0 : attributes.fileSize); if (size > INT64_MAX) @throw [OFOutOfRangeException exception]; entry.compressedSize = (int64_t)size; entry.uncompressedSize = (int64_t)size; entry.compressionMethod = OFZIPArchiveEntryCompressionMethodNone; entry.modificationDate = attributes.fileModificationDate; [entry makeImmutable]; output = [_archive streamForWritingEntry: entry]; if (!isDirectory) { |
︙ | ︙ | |||
484 485 486 487 488 489 490 | percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; | | | | | | 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | percent != newPercent) { OFString *percentString; percent = newPercent; percentString = [OFString stringWithFormat: @"%3u", percent]; [OFStdOut writeString: @"\r"]; [OFStdOut writeString: OF_LOCALIZED( @"adding_file_percent", @"Adding %[file]... %[percent]%", @"file", fileName, @"percent", percentString)]; } } } if (app->_outputLevel >= 0) { [OFStdOut writeString: @"\r"]; [OFStdOut writeLine: OF_LOCALIZED( @"adding_file_done", @"Adding %[file]... done", @"file", fileName)]; } [output close]; |
︙ | ︙ |
Modified utils/ofdns/OFDNS.m from [7cbfa15818] to [4408352570].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
33 34 35 36 37 38 39 | @end OF_APPLICATION_DELEGATE(OFDNS) static void help(OFStream *stream, bool full, int status) { | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | @end OF_APPLICATION_DELEGATE(OFDNS) static void help(OFStream *stream, bool full, int status) { [OFStdErr writeLine: OF_LOCALIZED(@"usage", @"Usage: %[prog] -[chst] domain1 [domain2 ...]", @"prog", [OFApplication programName])]; if (full) { [stream writeString: @"\n"]; [stream writeLine: OF_LOCALIZED(@"full_usage", |
︙ | ︙ | |||
65 66 67 68 69 70 71 | didPerformQuery: (OFDNSQuery *)query response: (OFDNSResponse *)response exception: (id)exception { _inFlight--; if (exception == nil) | | | | | | | | | | | | | | < | | | < | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | didPerformQuery: (OFDNSQuery *)query response: (OFDNSResponse *)response exception: (id)exception { _inFlight--; if (exception == nil) [OFStdOut writeFormat: @"%@\n", response]; else { [OFStdErr writeLine: OF_LOCALIZED( @"failed_to_resolve", @"Failed to resolve: %[exception]", @"exception", exception)]; _errors++; } if (_inFlight == 0) [OFApplication terminateWithStatus: _errors]; } - (void)applicationDidFinishLaunching { OFString *DNSClassString, *server; const OFOptionsParserOption options[] = { { 'c', @"class", 1, NULL, &DNSClassString }, { 'h', @"help", 0, NULL, NULL }, { 's', @"server", 1, NULL, &server }, { 't', @"type", 1, NULL, NULL }, { '\0', nil, 0, NULL, NULL } }; OFMutableArray OF_GENERIC(OFString *) *recordTypes; OFOptionsParser *optionsParser; OFUnichar option; OFArray OF_GENERIC(OFString *) *remainingArguments; OFDNSResolver *resolver; OFDNSClass DNSClass; #ifdef OF_HAVE_FILES # ifndef OF_AMIGAOS [OFLocale addLanguageDirectory: @LANGUAGE_DIR]; # else [OFLocale addLanguageDirectory: @"PROGDIR:/share/ofdns/lang"]; # endif #endif #ifdef OF_HAVE_SANDBOX OFSandbox *sandbox = [[OFSandbox alloc] init]; @try { sandbox.allowsStdIO = true; sandbox.allowsDNS = true; [OFApplication of_activateSandbox: sandbox]; } @finally { [sandbox release]; } #endif recordTypes = [OFMutableArray array]; optionsParser = [OFOptionsParser parserWithOptions: options]; while ((option = [optionsParser nextOption]) != '\0') { switch (option) { case 't': [recordTypes addObject: optionsParser.argument]; break; case 'h': help(OFStdOut, true, 0); break; case ':': if (optionsParser.lastLongOption != nil) [OFStdErr writeLine: OF_LOCALIZED( @"long_option_required_argument", @"%[prog]: Option --%[opt] requires an " @"argument", @"prog", [OFApplication programName], @"opt", optionsParser.lastLongOption)]; else { OFString *optStr = [OFString stringWithFormat: @"%C", optionsParser.lastOption]; [OFStdErr writeLine: OF_LOCALIZED( @"option_requires_argument", @"%[prog]: Option -%[opt] requires an " @"argument", @"prog", [OFApplication programName], @"opt", optStr)]; } [OFApplication terminateWithStatus: 1]; break; case '?': if (optionsParser.lastLongOption != nil) [OFStdErr writeLine: OF_LOCALIZED( @"unknown_long_option", @"%[prog]: Unknown option: --%[opt]", @"prog", [OFApplication programName], @"opt", optionsParser.lastLongOption)]; else { OFString *optStr = [OFString stringWithFormat: @"%C", optionsParser.lastOption]; [OFStdErr writeLine: OF_LOCALIZED( @"Unknown_option", @"%[prog]: Unknown option: -%[opt]", @"prog", [OFApplication programName], @"opt", optStr)]; } [OFApplication terminateWithStatus: 1]; break; } } remainingArguments = optionsParser.remainingArguments; if (remainingArguments.count < 1) help(OFStdErr, false, 1); resolver = [OFDNSResolver resolver]; DNSClass = (DNSClassString != nil ? OFDNSClassParseName(DNSClassString) : OFDNSClassIN); if (recordTypes.count == 0) [recordTypes addObject: @"ALL"]; if (server != nil) { resolver.configReloadInterval = 0; resolver.nameServers = [OFArray arrayWithObject: server]; } for (OFString *domainName in remainingArguments) { for (OFString *recordTypeString in recordTypes) { OFDNSRecordType recordType = OFDNSRecordTypeParseName(recordTypeString); OFDNSQuery *query = [OFDNSQuery queryWithDomainName: domainName DNSClass: DNSClass recordType: recordType]; _inFlight++; [resolver asyncPerformQuery: query delegate: self]; } } } @end |
Modified utils/ofhash/OFHash.m from [58d815f0b3] to [1e29e681a3].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
40 41 42 43 44 45 46 | @end OF_APPLICATION_DELEGATE(OFHash) static void help(void) { | | | | | > | > > | | | | | | | | | < | < | | | < | < | < | < | < | | | < | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | @end OF_APPLICATION_DELEGATE(OFHash) static void help(void) { [OFStdErr writeLine: OF_LOCALIZED(@"usage", @"Usage: %[prog] [--md5] [--ripemd160] [--sha1] [--sha224] " @"[--sha256] [--sha384] [--sha512] file1 [file2 ...]", @"prog", [OFApplication programName])]; [OFApplication terminateWithStatus: 1]; } static void printHash(OFString *algo, OFString *path, id <OFCryptographicHash> hash) { size_t digestSize = hash.digestSize; const unsigned char *digest; [hash calculate]; digest = hash.digest; [OFStdOut writeFormat: @"%@ ", algo]; for (size_t i = 0; i < digestSize; i++) [OFStdOut writeFormat: @"%02x", digest[i]]; [OFStdOut writeFormat: @" %@\n", path]; } @implementation OFHash - (void)applicationDidFinishLaunching { int exitStatus = 0; bool calculateMD5, calculateRIPEMD160, calculateSHA1, calculateSHA224; bool calculateSHA256, calculateSHA384, calculateSHA512; const OFOptionsParserOption options[] = { { '\0', @"md5", 0, &calculateMD5, NULL }, { '\0', @"ripemd160", 0, &calculateRIPEMD160, NULL }, { '\0', @"sha1", 0, &calculateSHA1, NULL }, { '\0', @"sha224", 0, &calculateSHA224, NULL }, { '\0', @"sha256", 0, &calculateSHA256, NULL }, { '\0', @"sha384", 0, &calculateSHA384, NULL }, { '\0', @"sha512", 0, &calculateSHA512, NULL }, { '\0', nil, 0, NULL, NULL } }; OFOptionsParser *optionsParser = [OFOptionsParser parserWithOptions: options]; OFUnichar option; OFMD5Hash *MD5Hash = nil; OFRIPEMD160Hash *RIPEMD160Hash = nil; OFSHA1Hash *SHA1Hash = nil; OFSHA224Hash *SHA224Hash = nil; OFSHA256Hash *SHA256Hash = nil; OFSHA384Hash *SHA384Hash = nil; OFSHA512Hash *SHA512Hash = nil; #ifndef OF_AMIGAOS [OFLocale addLanguageDirectory: @LANGUAGE_DIR]; #else [OFLocale addLanguageDirectory: @"PROGDIR:/share/ofhash/lang"]; #endif while ((option = [optionsParser nextOption]) != '\0') { switch (option) { case '?': if (optionsParser.lastLongOption != nil) [OFStdErr writeLine: OF_LOCALIZED(@"unknown_long_option", @"%[prog]: Unknown option: --%[opt]", @"prog", [OFApplication programName], @"opt", optionsParser.lastLongOption)]; else { OFString *optStr = [OFString stringWithFormat: @"%c", optionsParser.lastOption]; [OFStdErr writeLine: OF_LOCALIZED(@"unknown_option", @"%[prog]: Unknown option: -%[opt]", @"prog", [OFApplication programName], @"opt", optStr)]; } [OFApplication terminateWithStatus: 1]; break; } } #ifdef OF_HAVE_SANDBOX OFSandbox *sandbox = [OFSandbox sandbox]; @try { sandbox.allowsStdIO = true; sandbox.allowsReadingFiles = true; sandbox.allowsUserDatabaseReading = true; for (OFString *path in optionsParser.remainingArguments) [sandbox unveilPath: path permissions: @"r"]; [sandbox unveilPath: @LANGUAGE_DIR permissions: @"r"]; [OFApplication of_activateSandbox: sandbox]; } @finally { [sandbox release]; } #endif if (!calculateMD5 && !calculateRIPEMD160 && !calculateSHA1 && !calculateSHA224 && !calculateSHA256 && !calculateSHA384 && !calculateSHA512) help(); if (optionsParser.remainingArguments.count < 1) help(); if (calculateMD5) MD5Hash = [OFMD5Hash hashWithAllowsSwappableMemory: true]; if (calculateRIPEMD160) RIPEMD160Hash = [OFRIPEMD160Hash hashWithAllowsSwappableMemory: true]; if (calculateSHA1) SHA1Hash = [OFSHA1Hash hashWithAllowsSwappableMemory: true]; if (calculateSHA224) SHA224Hash = [OFSHA224Hash hashWithAllowsSwappableMemory: true]; if (calculateSHA256) SHA256Hash = [OFSHA256Hash hashWithAllowsSwappableMemory: true]; if (calculateSHA384) SHA384Hash = [OFSHA384Hash hashWithAllowsSwappableMemory: true]; if (calculateSHA512) SHA512Hash = [OFSHA512Hash hashWithAllowsSwappableMemory: true]; for (OFString *path in optionsParser.remainingArguments) { void *pool = objc_autoreleasePoolPush(); OFStream *file; if ([path isEqual: @"-"]) file = OFStdIn; else { @try { file = [OFFile fileWithPath: path mode: @"r"]; } @catch (OFOpenItemFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; [OFStdErr writeLine: OF_LOCALIZED( @"failed_to_open_file", @"Failed to open file %[file]: %[error]", @"file", e.path, @"error", error)]; exitStatus = 1; goto outer_loop_end; |
︙ | ︙ | |||
214 215 216 217 218 219 220 | length = [file readIntoBuffer: buffer length: 1024]; } @catch (OFReadFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; | | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | length = [file readIntoBuffer: buffer length: 1024]; } @catch (OFReadFailedException *e) { OFString *error = [OFString stringWithCString: strerror(e.errNo) encoding: [OFLocale encoding]]; [OFStdErr writeLine: OF_LOCALIZED( @"failed_to_read_file", @"Failed to read %[file]: %[error]", @"file", path, @"error", error)]; exitStatus = 1; goto outer_loop_end; |
︙ | ︙ |
Modified utils/ofhash/lang/de.json from [775fc52ec2] to [e3d21e1de1].
1 2 | { "usage": [ | | | | 1 2 3 4 5 6 7 8 9 10 | { "usage": [ "Benutzung: %[prog] [--md5] [--ripemd160] [--sha1] [--sha224] ", "[--sha256] [--sha384] [--sha512] datei1 [datei2 ...]" ], "unknown_long_option": "%[prog]: Unbekannte Option: --%[opt]", "unknown_option": "%[prog]: Unbekannte Option: -%[opt]", "failed_to_open_file": "Fehler beim Öffnen der Datei %[file]: %[error]", "failed_to_read_file": "Fehler beim Lesen der Datei %[file]: %[error]" } |
Modified utils/ofhttp/Makefile from [ca0ac82289] to [a12779af52].
︙ | ︙ | |||
11 12 13 14 15 16 17 18 | PACKAGE_NAME = ofhttp ${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2} CPPFLAGS += -I../../src \ -I../../src/runtime \ -I../../src/exceptions \ -I../.. \ | > | > > | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | PACKAGE_NAME = ofhttp ${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2} CPPFLAGS += -I../../src \ -I../../src/runtime \ -I../../src/exceptions \ -I../../src/tls \ -I../.. \ -DLANGUAGE_DIR='"${datadir}/ofhttp/lang"' \ -DLIB_PREFIX='"${LIB_PREFIX}"' \ -DLIB_SUFFIX='"${LIB_SUFFIX}"' LIBS := -L../../src -L../../src/tls ${OFHTTP_LIBS} -lobjfw \ -L../../src/runtime -L../../src/runtime/linklib ${RUNTIME_LIBS} \ ${LIBS} LD = ${OBJC} LDFLAGS += ${LDFLAGS_RPATH} |
Modified utils/ofhttp/OFHTTP.m from [c172d83732] to [aa1d962c4e].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
31 32 33 34 35 36 37 | #ifdef OF_HAVE_PLUGINS # import "OFPlugin.h" #endif #import "OFSandbox.h" #import "OFStdIOStream.h" #import "OFSystemInfo.h" #import "OFTCPSocket.h" | | > > > > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #ifdef OF_HAVE_PLUGINS # import "OFPlugin.h" #endif #import "OFSandbox.h" #import "OFStdIOStream.h" #import "OFSystemInfo.h" #import "OFTCPSocket.h" #import "OFTLSStream.h" #import "OFURL.h" #ifdef HAVE_TLS_SUPPORT # import "ObjFWTLS.h" #endif #import "OFConnectionFailedException.h" #import "OFHTTPRequestFailedException.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFInvalidServerReplyException.h" #import "OFOpenItemFailedException.h" |
︙ | ︙ | |||
62 63 64 65 66 67 68 69 | { OFArray OF_GENERIC(OFString *) *_URLs; size_t _URLIndex; int _errorCode; OFString *_outputPath, *_currentFileName; bool _continue, _force, _detectFileName, _detectFileNameRequest; bool _detectedFileName, _quiet, _verbose, _insecure, _ignoreStatus; OFStream *_body; | > | > > > > > > > > | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | { OFArray OF_GENERIC(OFString *) *_URLs; size_t _URLIndex; int _errorCode; OFString *_outputPath, *_currentFileName; bool _continue, _force, _detectFileName, _detectFileNameRequest; bool _detectedFileName, _quiet, _verbose, _insecure, _ignoreStatus; bool _useUnicode; OFStream *_body; OFHTTPRequestMethod _method; OFMutableDictionary *_clientHeaders; OFHTTPClient *_HTTPClient; char *_buffer; OFStream *_output; unsigned long long _received, _length, _resumedFrom; ProgressBar *_progressBar; } - (void)downloadNextURL; @end #ifdef HAVE_TLS_SUPPORT void _reference_to_ObjFWTLS(void) { _ObjFWTLS_reference = 1; } #endif OF_APPLICATION_DELEGATE(OFHTTP) static void help(OFStream *stream, bool full, int status) { [OFStdErr writeLine: OF_LOCALIZED(@"usage", @"Usage: %[prog] -[cehHmoOPqv] url1 [url2 ...]", @"prog", [OFApplication programName])]; if (full) { [stream writeString: @"\n"]; [stream writeLine: OF_LOCALIZED(@"full_usage", |
︙ | ︙ | |||
129 130 131 132 133 134 135 | static OFString * fileNameFromContentDisposition(OFString *contentDisposition) { void *pool; const char *UTF8String; size_t UTF8StringLength; enum { | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < < < < < < < < < < | | | | | < | | < | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 | static OFString * fileNameFromContentDisposition(OFString *contentDisposition) { void *pool; const char *UTF8String; size_t UTF8StringLength; enum { stateDispositionType, stateDispositionTypeSemicolon, stateDispositionParamNameSkipSpace, stateDispositionParamName, stateDispositionParamValue, stateDispositionParamQuoted, stateDispositionParamUnquoted, stateDispositionExpectSemicolon } state; size_t last; OFString *type = nil, *paramName = nil, *paramValue; OFMutableDictionary *params; OFString *fileName; if (contentDisposition == nil) return nil; pool = objc_autoreleasePoolPush(); UTF8String = contentDisposition.UTF8String; UTF8StringLength = contentDisposition.UTF8StringLength; state = stateDispositionType; params = [OFMutableDictionary dictionary]; last = 0; for (size_t i = 0; i < UTF8StringLength; i++) { switch (state) { case stateDispositionType: if (UTF8String[i] == ';' || UTF8String[i] == ' ') { type = [OFString stringWithUTF8String: UTF8String length: i]; state = (UTF8String[i] == ';' ? stateDispositionParamNameSkipSpace : stateDispositionTypeSemicolon); last = i + 1; } break; case stateDispositionTypeSemicolon: if (UTF8String[i] == ';') { state = stateDispositionParamNameSkipSpace; last = i + 1; } else if (UTF8String[i] != ' ') { objc_autoreleasePoolPop(pool); return nil; } break; case stateDispositionParamNameSkipSpace: if (UTF8String[i] != ' ') { state = stateDispositionParamName; last = i; i--; } break; case stateDispositionParamName: if (UTF8String[i] == '=') { paramName = [OFString stringWithUTF8String: UTF8String + last length: i - last]; state = stateDispositionParamValue; } break; case stateDispositionParamValue: if (UTF8String[i] == '"') { state = stateDispositionParamQuoted; last = i + 1; } else { state = stateDispositionParamUnquoted; last = i; i--; } break; case stateDispositionParamQuoted: if (UTF8String[i] == '"') { paramValue = [OFString stringWithUTF8String: UTF8String + last length: i - last]; [params setObject: paramValue forKey: paramName.lowercaseString]; state = stateDispositionExpectSemicolon; } break; case stateDispositionParamUnquoted: if (UTF8String[i] <= 31 || UTF8String[i] >= 127) return nil; switch (UTF8String[i]) { case ' ': case '"': case '(': case ')': case ',': case '/': case ':': case '<': case '=': case '>': case '?': case '@': case '[': case '\\': case ']': case '{': case '}': return nil; case ';': paramValue = [OFString stringWithUTF8String: UTF8String + last length: i - last]; [params setObject: paramValue forKey: paramName.lowercaseString]; state = stateDispositionParamNameSkipSpace; break; } break; case stateDispositionExpectSemicolon: if (UTF8String[i] == ';') { state = stateDispositionParamNameSkipSpace; last = i + 1; } else if (UTF8String[i] != ' ') { objc_autoreleasePoolPop(pool); return nil; } break; } } if (state == stateDispositionParamUnquoted) { paramValue = [OFString stringWithUTF8String: UTF8String + last length: UTF8StringLength - last]; [params setObject: paramValue forKey: paramName.lowercaseString]; } else if (state != stateDispositionExpectSemicolon) { objc_autoreleasePoolPop(pool); return nil; } if (![type isEqual: @"attachment"] || (fileName = [params objectForKey: @"filename"]) == nil) { objc_autoreleasePoolPop(pool); return nil; } fileName = fileName.lastPathComponent; [fileName retain]; objc_autoreleasePoolPop(pool); return [fileName autorelease]; } @implementation OFHTTP - (instancetype)init { self = [super init]; @try { _method = OFHTTPRequestMethodGet; _clientHeaders = [[OFMutableDictionary alloc] initWithObject: @"OFHTTP" forKey: @"User-Agent"]; _HTTPClient = [[OFHTTPClient alloc] init]; _HTTPClient.delegate = self; _buffer = OFAllocMemory(1, [OFSystemInfo pageSize]); } @catch (id e) { [self release]; @throw e; } return self; } - (void)addHeader: (OFString *)header { size_t pos = [header rangeOfString: @":"].location; OFString *name, *value; if (pos == OFNotFound) { [OFStdErr writeLine: OF_LOCALIZED(@"invalid_input_header", @"%[prog]: Headers must to be in format name:value!", @"prog", [OFApplication programName])]; [OFApplication terminateWithStatus: 1]; } name = [header substringToIndex: pos] .stringByDeletingEnclosingWhitespaces; value = [header substringFromIndex: pos + 1] .stringByDeletingEnclosingWhitespaces; [_clientHeaders setObject: value forKey: name]; } - (void)setBody: (OFString *)path { OFString *contentLength = nil; [_body release]; _body = nil; if ([path isEqual: @"-"]) _body = [OFStdIn copy]; else { _body = [[OFFile alloc] initWithPath: path mode: @"r"]; @try { unsigned long long fileSize = [[OFFileManager defaultManager] attributesOfItemAtPath: path].fileSize; contentLength = |
︙ | ︙ | |||
369 370 371 372 373 374 375 | - (void)setMethod: (OFString *)method { void *pool = objc_autoreleasePoolPush(); method = method.uppercaseString; @try { | | | | | | | | | | | | | | | > | > > > | | > | | < | | | | | > > > > > > | < | | | < > | < < < | < | < | < | > | > > > | | | < < | < > | | | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | - (void)setMethod: (OFString *)method { void *pool = objc_autoreleasePoolPush(); method = method.uppercaseString; @try { _method = OFHTTPRequestMethodParseName(method); } @catch (OFInvalidArgumentException *e) { [OFStdErr writeLine: OF_LOCALIZED(@"invalid_input_method", @"%[prog]: Invalid request method %[method]!", @"prog", [OFApplication programName], @"method", method)]; [OFApplication terminateWithStatus: 1]; } objc_autoreleasePoolPop(pool); } - (void)setProxy: (OFString *)proxy { @try { size_t pos = [proxy rangeOfString: @":" options: OFStringSearchBackwards].location; OFString *host; unsigned long long port; if (pos == OFNotFound) @throw [OFInvalidFormatException exception]; host = [proxy substringToIndex: pos]; port = [proxy substringFromIndex: pos + 1] .unsignedLongLongValue; if (port > UINT16_MAX) @throw [OFOutOfRangeException exception]; [OFTCPSocket setSOCKS5Host: host]; [OFTCPSocket setSOCKS5Port: (uint16_t)port]; } @catch (OFInvalidFormatException *e) { [OFStdErr writeLine: OF_LOCALIZED(@"invalid_input_proxy", @"%[prog]: Proxy must to be in format host:port!", @"prog", [OFApplication programName])]; [OFApplication terminateWithStatus: 1]; } } - (void)applicationDidFinishLaunching { OFString *outputPath; const OFOptionsParserOption options[] = { { 'b', @"body", 1, NULL, NULL }, { 'c', @"continue", 0, &_continue, NULL }, { 'f', @"force", 0, &_force, NULL }, { 'h', @"help", 0, NULL, NULL }, { 'H', @"header", 1, NULL, NULL }, { 'm', @"method", 1, NULL, NULL }, { 'o', @"output", 1, NULL, &outputPath }, { 'O', @"detect-filename", 0, &_detectFileName, NULL }, { 'P', @"socks5-proxy", 1, NULL, NULL }, { 'q', @"quiet", 0, &_quiet, NULL }, { 'v', @"verbose", 0, &_verbose, NULL }, { '\0', @"insecure", 0, &_insecure, NULL }, { '\0', @"ignore-status", 0, &_ignoreStatus, NULL }, { '\0', nil, 0, NULL, NULL } }; OFOptionsParser *optionsParser; OFUnichar option; #ifdef OF_HAVE_SANDBOX OFSandbox *sandbox = [OFSandbox sandbox]; sandbox.allowsStdIO = true; sandbox.allowsReadingFiles = true; sandbox.allowsWritingFiles = true; sandbox.allowsCreatingFiles = true; sandbox.allowsIPSockets = true; sandbox.allowsDNS = true; sandbox.allowsUserDatabaseReading = true; sandbox.allowsTTY = true; /* Dropped after parsing options */ sandbox.allowsUnveil = true; [OFApplication of_activateSandbox: sandbox]; #endif #ifndef OF_AMIGAOS [OFLocale addLanguageDirectory: @LANGUAGE_DIR]; #else [OFLocale addLanguageDirectory: @"PROGDIR:/share/ofhttp/lang"]; #endif optionsParser = [OFOptionsParser parserWithOptions: options]; while ((option = [optionsParser nextOption]) != '\0') { switch (option) { case 'b': [self setBody: optionsParser.argument]; break; case 'h': help(OFStdOut, true, 0); break; case 'H': [self addHeader: optionsParser.argument]; break; case 'm': [self setMethod: optionsParser.argument]; break; case 'P': [self setProxy: optionsParser.argument]; break; case ':': if (optionsParser.lastLongOption != nil) [OFStdErr writeLine: OF_LOCALIZED(@"long_argument_missing", @"%[prog]: Argument for option --%[opt] " @"missing" @"prog", [OFApplication programName], @"opt", optionsParser.lastLongOption)]; else { OFString *optStr = [OFString stringWithFormat: @"%c", optionsParser.lastOption]; [OFStdErr writeLine: OF_LOCALIZED(@"argument_missing", @"%[prog]: Argument for option -%[opt] " @"missing", @"prog", [OFApplication programName], @"opt", optStr)]; } [OFApplication terminateWithStatus: 1]; break; case '=': [OFStdErr writeLine: OF_LOCALIZED(@"option_takes_no_argument", @"%[prog]: Option --%[opt] takes no argument", @"prog", [OFApplication programName], @"opt", optionsParser.lastLongOption)]; [OFApplication terminateWithStatus: 1]; break; case '?': if (optionsParser.lastLongOption != nil) [OFStdErr writeLine: OF_LOCALIZED(@"unknown_long_option", @"%[prog]: Unknown option: --%[opt]", @"prog", [OFApplication programName], @"opt", optionsParser.lastLongOption)]; else { OFString *optStr = [OFString stringWithFormat: @"%c", optionsParser.lastOption]; [OFStdErr writeLine: OF_LOCALIZED(@"unknown_option", @"%[prog]: Unknown option: -%[opt]", @"prog", [OFApplication programName], @"opt", optStr)]; } [OFApplication terminateWithStatus: 1]; break; } } #ifdef OF_HAVE_SANDBOX if (outputPath != nil) [sandbox unveilPath: outputPath permissions: (_continue ? @"rwc" : @"wc")]; else [sandbox unveilPath: [[OFFileManager defaultManager] currentDirectoryPath] permissions: (_continue ? @"rwc" : @"wc")]; /* In case we use OpenSSL for HTTPS later */ [sandbox unveilPath: @"/etc/ssl" permissions: @"r"]; sandbox.allowsUnveil = false; [OFApplication of_activateSandbox: sandbox]; #endif _outputPath = [outputPath copy]; _URLs = [optionsParser.remainingArguments copy]; if (_URLs.count < 1) help(OFStdErr, false, 1); if (_quiet && _verbose) { [OFStdErr writeLine: OF_LOCALIZED(@"quiet_xor_verbose", @"%[prog]: -q / --quiet and -v / --verbose are mutually " @"exclusive!", @"prog", [OFApplication programName])]; [OFApplication terminateWithStatus: 1]; } if (_outputPath != nil && _detectFileName) { [OFStdErr writeLine: OF_LOCALIZED( @"output_xor_detect_filename", @"%[prog]: -o / --output and -O / --detect-filename are " @"mutually exclusive!", @"prog", [OFApplication programName])]; [OFApplication terminateWithStatus: 1]; } if (_outputPath != nil && _URLs.count > 1) { [OFStdErr writeLine: OF_LOCALIZED(@"output_only_with_one_url", @"%[prog]: Cannot use -o / --output when more than one URL " @"has been specified!", @"prog", [OFApplication programName])]; [OFApplication terminateWithStatus: 1]; } if (_insecure) _HTTPClient.allowsInsecureRedirects = true; #ifdef OF_WINDOWS _useUnicode = [OFSystemInfo isWindowsNT]; #else _useUnicode = ([OFLocale encoding] == OFStringEncodingUTF8); #endif [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } - (void)client: (OFHTTPClient *)client didCreateTLSStream: (OFTLSStream *)stream request: (OFHTTPRequest *)request { /* Use setter instead of property access to work around GCC bug. */ [stream setVerifiesCertificates: !_insecure]; } - (void)client: (OFHTTPClient *)client wantsRequestBody: (OFStream *)body request: (OFHTTPRequest *)request { /* TODO: Do asynchronously and print status */ while (!_body.atEndOfStream) { char buffer[4096]; size_t length = [_body readIntoBuffer: buffer length: 4096]; [body writeBuffer: buffer length: length]; } } - (bool)client: (OFHTTPClient *)client shouldFollowRedirect: (OFURL *)URL statusCode: (short)statusCode request: (OFHTTPRequest *)request response: (OFHTTPResponse *)response { if (_verbose) { void *pool = objc_autoreleasePoolPush(); OFDictionary OF_GENERIC(OFString *, OFString *) *headers = response.headers; OFEnumerator *keyEnumerator = [headers keyEnumerator]; OFEnumerator *objectEnumerator = [headers objectEnumerator]; OFString *key, *object; while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) [OFStdOut writeFormat: @" %@: %@\n", key, object]; objc_autoreleasePoolPop(pool); } if (!_quiet) { if (_useUnicode) [OFStdOut writeFormat: @"☇ %@", URL.string]; else [OFStdOut writeFormat: @"< %@", URL.string]; } _length = 0; return true; } - (bool)stream: (OFStream *)response didReadIntoBuffer: (void *)buffer length: (size_t)length exception: (id)exception { if (exception != nil) { OFString *URL; [_progressBar stop]; [_progressBar draw]; [_progressBar release]; _progressBar = nil; if (!_quiet) { [OFStdOut writeString: @"\n "]; [OFStdOut writeLine: OF_LOCALIZED(@"download_error", @"Error!")]; } URL = [_URLs objectAtIndex: _URLIndex - 1]; [OFStdErr writeLine: OF_LOCALIZED( @"download_failed_exception", @"%[prog]: Failed to download <%[url]>!\n" @" %[exception]", @"prog", [OFApplication programName], @"url", URL, @"exception", exception)]; _errorCode = 1; [self performSelector: @selector(downloadNextURL) afterDelay: 0]; return false; } [_output writeBuffer: buffer length: length]; _received += length; [_progressBar setReceived: _received]; if (response.atEndOfStream) { [_progressBar stop]; [_progressBar draw]; [_progressBar release]; _progressBar = nil; if (!_quiet) { [OFStdOut writeString: @"\n "]; [OFStdOut writeLine: OF_LOCALIZED(@"download_done", @"Done!")]; } [self performSelector: @selector(downloadNextURL) afterDelay: 0]; return false; } |
︙ | ︙ | |||
706 707 708 709 710 711 712 | _resumedFrom = 0; if (!_quiet) { OFString *lengthString = [headers objectForKey: @"Content-Length"]; OFString *type = [headers objectForKey: @"Content-Type"]; | > | > > | 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 | _resumedFrom = 0; if (!_quiet) { OFString *lengthString = [headers objectForKey: @"Content-Length"]; OFString *type = [headers objectForKey: @"Content-Type"]; if (_useUnicode) [OFStdOut writeFormat: @" ➜ %hd\n", statusCode]; else [OFStdOut writeFormat: @" -> %hd\n", statusCode]; if (type == nil) type = OF_LOCALIZED(@"type_unknown", @"unknown"); if (lengthString != nil) { _length = lengthString.unsignedLongLongValue; |
︙ | ︙ | |||
760 761 762 763 764 765 766 | OFEnumerator OF_GENERIC(OFString *) *keyEnumerator = [headers keyEnumerator]; OFEnumerator OF_GENERIC(OFString *) *objectEnumerator = [headers objectEnumerator]; OFString *key, *object; if (statusCode / 100 == 2 && _currentFileName != nil) { | | | | | | > > | | | > | | | | | | | | | | | | | | | | > | | | < | | | | | | > | < | < | | | | > | > > > | > > > > > > > > | < | > | > > > | < | 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 | OFEnumerator OF_GENERIC(OFString *) *keyEnumerator = [headers keyEnumerator]; OFEnumerator OF_GENERIC(OFString *) *objectEnumerator = [headers objectEnumerator]; OFString *key, *object; if (statusCode / 100 == 2 && _currentFileName != nil) { [OFStdOut writeString: @" "]; [OFStdOut writeLine: OF_LOCALIZED( @"info_name_unaligned", @"Name: %[name]", @"name", _currentFileName)]; } while ((key = [keyEnumerator nextObject]) != nil && (object = [objectEnumerator nextObject]) != nil) [OFStdOut writeFormat: @" %@: %@\n", key, object]; objc_autoreleasePoolPop(pool); } else if (statusCode / 100 == 2 && !_detectFileNameRequest) { [OFStdOut writeString: @" "]; if (_currentFileName != nil) [OFStdOut writeLine: OF_LOCALIZED(@"info_name", @"Name: %[name]", @"name", _currentFileName)]; [OFStdOut writeString: @" "]; [OFStdOut writeLine: OF_LOCALIZED(@"info_type", @"Type: %[type]", @"type", type)]; [OFStdOut writeString: @" "]; [OFStdOut writeLine: OF_LOCALIZED(@"info_size", @"Size: %[size]", @"size", lengthString)]; } } } - (void)client: (OFHTTPClient *)client didPerformRequest: (OFHTTPRequest *)request response: (OFHTTPResponse *)response exception: (id)exception { if (exception != nil) { if ([exception isKindOfClass: [OFResolveHostFailedException class]]) { if (!_quiet) [OFStdOut writeString: @"\n"]; [OFStdErr writeLine: OF_LOCALIZED(@"download_resolve_host_failed", @"%[prog]: Failed to download <%[url]>!\n" @" Failed to resolve host: %[exception]", @"prog", [OFApplication programName], @"url", request.URL.string, @"exception", exception)]; } else if ([exception isKindOfClass: [OFConnectionFailedException class]]) { if (!_quiet) [OFStdOut writeString: @"\n"]; [OFStdErr writeLine: OF_LOCALIZED(@"download_failed_connection_failed", @"%[prog]: Failed to download <%[url]>!\n" @" Connection failed: %[exception]", @"prog", [OFApplication programName], @"url", request.URL.string, @"exception", exception)]; } else if ([exception isKindOfClass: [OFInvalidServerReplyException class]]) { if (!_quiet) [OFStdOut writeString: @"\n"]; [OFStdErr writeLine: OF_LOCALIZED( @"download_failed_invalid_server_reply", @"%[prog]: Failed to download <%[url]>!\n" @" Invalid server reply!", @"prog", [OFApplication programName], @"url", request.URL.string)]; } else if ([exception isKindOfClass: [OFUnsupportedProtocolException class]]) { if (!_quiet) [OFStdOut writeString: @"\n"]; [OFStdErr writeLine: OF_LOCALIZED(@"no_tls_support", @"%[prog]: No TLS support in ObjFW!\n" @" In order to download via HTTPS, you need to " @"either build ObjFW with TLS\n" @" support or preload a library adding TLS " @"support to ObjFW!", @"prog", [OFApplication programName])]; } else if ([exception isKindOfClass: [OFReadOrWriteFailedException class]]) { OFString *error = OF_LOCALIZED( @"download_failed_read_or_write_failed_any", @"Read or write failed"); if (!_quiet) [OFStdOut writeString: @"\n"]; if ([exception isKindOfClass: [OFReadFailedException class]]) error = OF_LOCALIZED( @"download_failed_read_or_write_failed_" @"read", @"Read failed"); else if ([exception isKindOfClass: [OFWriteFailedException class]]) error = OF_LOCALIZED( @"download_failed_read_or_write_failed_" @"write", @"Write failed"); [OFStdErr writeLine: OF_LOCALIZED( @"download_failed_read_or_write_failed", @"%[prog]: Failed to download <%[url]>!\n" @" %[error]: %[exception]", @"prog", [OFApplication programName], @"url", request.URL.string, @"error", error, @"exception", exception)]; } else if ([exception isKindOfClass: [OFHTTPRequestFailedException class]]) { short statusCode; OFString *codeString; if (_ignoreStatus) { exception = nil; goto after_exception_handling; } statusCode = response.statusCode; codeString = [OFString stringWithFormat: @"%hd %@", statusCode, OFHTTPStatusCodeString(statusCode)]; [OFStdErr writeLine: OF_LOCALIZED(@"download_failed", @"%[prog]: Failed to download <%[url]>!\n" @" HTTP status code: %[code]", @"prog", [OFApplication programName], @"url", request.URL.string, @"code", codeString)]; } else @throw exception; _errorCode = 1; [self performSelector: @selector(downloadNextURL) afterDelay: 0]; return; } after_exception_handling: if (_method == OFHTTPRequestMethodHead) goto next; if (_detectFileNameRequest) { _currentFileName = [fileNameFromContentDisposition( [response.headers objectForKey: @"Content-Disposition"]) copy]; _detectedFileName = true; /* Handle this URL on the next -[downloadNextURL] call */ _URLIndex--; [self performSelector: @selector(downloadNextURL) afterDelay: 0]; return; } if ([_outputPath isEqual: @"-"]) _output = [OFStdOut copy]; else { if (!_continue && !_force && [[OFFileManager defaultManager] fileExistsAtPath: _currentFileName]) { [OFStdErr writeLine: OF_LOCALIZED(@"output_already_exists", @"%[prog]: File %[filename] already exists!", @"prog", [OFApplication programName], @"filename", _currentFileName)]; _errorCode = 1; goto next; } @try { OFString *mode = (response.statusCode == 206 ? @"a" : @"w"); _output = [[OFFile alloc] initWithPath: _currentFileName mode: mode]; } @catch (OFOpenItemFailedException *e) { [OFStdErr writeLine: OF_LOCALIZED(@"failed_to_open_output", @"%[prog]: Failed to open file %[filename]: " @"%[exception]", @"prog", [OFApplication programName], @"filename", _currentFileName, @"exception", e)]; _errorCode = 1; goto next; } } if (!_quiet) { _progressBar = [[ProgressBar alloc] initWithLength: _length resumedFrom: _resumedFrom useUnicode: _useUnicode]; [_progressBar setReceived: _received]; [_progressBar draw]; } [_currentFileName release]; _currentFileName = nil; response.delegate = self; [response asyncReadIntoBuffer: _buffer length: [OFSystemInfo pageSize]]; return; next: [_currentFileName release]; _currentFileName = nil; [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } - (void)downloadNextURL { OFString *URLString = nil; OFURL *URL; OFMutableDictionary *clientHeaders; OFHTTPRequest *request; _received = _length = _resumedFrom = 0; if (_output != OFStdOut) [_output release]; _output = nil; if (_URLIndex >= _URLs.count) [OFApplication terminateWithStatus: _errorCode]; @try { URLString = [_URLs objectAtIndex: _URLIndex++]; URL = [OFURL URLWithString: URLString]; } @catch (OFInvalidFormatException *e) { [OFStdErr writeLine: OF_LOCALIZED(@"invalid_url", @"%[prog]: Invalid URL: <%[url]>!", @"prog", [OFApplication programName], @"url", URLString)]; _errorCode = 1; goto next; } if (![URL.scheme isEqual: @"http"] && ![URL.scheme isEqual: @"https"]) { [OFStdErr writeLine: OF_LOCALIZED(@"invalid_scheme", @"%[prog]: Invalid scheme: <%[url]>!", @"prog", [OFApplication programName], @"url", URLString)]; _errorCode = 1; goto next; } clientHeaders = [[_clientHeaders mutableCopy] autorelease]; if (_detectFileName && !_detectedFileName) { if (!_quiet) { if (_useUnicode) [OFStdOut writeFormat: @"⠒ %@", URL.string]; else [OFStdOut writeFormat: @"? %@", URL.string]; } request = [OFHTTPRequest requestWithURL: URL]; request.headers = clientHeaders; request.method = OFHTTPRequestMethodHead; _detectFileNameRequest = true; [_HTTPClient asyncPerformRequest: request]; return; } if (!_detectedFileName) { [_currentFileName release]; _currentFileName = nil; } else _detectedFileName = false; if (_currentFileName == nil) _currentFileName = [_outputPath copy]; if (_currentFileName == nil) _currentFileName = [URL.path.lastPathComponent copy]; if ([_currentFileName isEqual: @"/"]) { [_currentFileName release]; _currentFileName = nil; } if (_currentFileName == nil) _currentFileName = @"unnamed"; if (_continue) { @try { unsigned long long size = [[OFFileManager defaultManager] attributesOfItemAtPath: _currentFileName].fileSize; OFString *range; if (size > ULLONG_MAX) @throw [OFOutOfRangeException exception]; _resumedFrom = (unsigned long long)size; range = [OFString stringWithFormat: @"bytes=%jd-", _resumedFrom]; [clientHeaders setObject: range forKey: @"Range"]; } @catch (OFRetrieveItemAttributesFailedException *e) { } } if (!_quiet) { if (_useUnicode) [OFStdOut writeFormat: @"⇣ %@", URL.string]; else [OFStdOut writeFormat: @"< %@", URL.string]; } request = [OFHTTPRequest requestWithURL: URL]; request.headers = clientHeaders; request.method = _method; _detectFileNameRequest = false; [_HTTPClient asyncPerformRequest: request]; return; next: [self performSelector: @selector(downloadNextURL) afterDelay: 0]; } @end |
Modified utils/ofhttp/ProgressBar.h from [187685081a] to [be2c97fe71].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | @class OFDate; @class OFTimer; #define BPS_WINDOW_SIZE 10 @interface ProgressBar: OFObject { unsigned long long _received, _lastReceived, _length, _resumedFrom; OFDate *_startDate, *_lastReceivedDate; OFTimer *_drawTimer, *_BPSTimer; bool _stopped; float _BPS; double _ETA; float _BPSWindow[BPS_WINDOW_SIZE]; size_t _BPSWindowIndex, _BPSWindowLength; } - (instancetype)initWithLength: (unsigned long long)length | > | > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | @class OFDate; @class OFTimer; #define BPS_WINDOW_SIZE 10 @interface ProgressBar: OFObject { bool _useUnicode; unsigned long long _received, _lastReceived, _length, _resumedFrom; OFDate *_startDate, *_lastReceivedDate; OFTimer *_drawTimer, *_BPSTimer; bool _stopped; float _BPS; double _ETA; float _BPSWindow[BPS_WINDOW_SIZE]; size_t _BPSWindowIndex, _BPSWindowLength; } - (instancetype)initWithLength: (unsigned long long)length resumedFrom: (unsigned long long)resumedFrom useUnicode: (bool)useUnicode OF_DESIGNATED_INITIALIZER; - (void)setReceived: (unsigned long long)received; - (void)draw; - (void)calculateBPSAndETA; - (void)stop; @end |
Modified utils/ofhttp/ProgressBar.m from [814de8c246] to [9a2768256d].
1 | /* | < < | | 1 2 3 4 5 6 7 8 9 | /* * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * |
︙ | ︙ | |||
22 23 24 25 26 27 28 | #import "OFDate.h" #import "OFStdIOStream.h" #import "OFTimer.h" #import "OFLocale.h" #import "ProgressBar.h" | > > | | > | > > > > > | > > > | | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | #import "OFDate.h" #import "OFStdIOStream.h" #import "OFTimer.h" #import "OFLocale.h" #import "ProgressBar.h" static const float oneKibibyte = 1024; static const float oneMebibyte = 1024 * 1024; static const float oneGibibyte = 1024 * 1024 * 1024; static const OFTimeInterval updateInterval = 0.1; #ifdef OF_MINT /* freemint-gcc does not have trunc() */ # define trunc(x) ((int64_t)(x)) #endif #ifndef HAVE_TRUNCF # define truncf(x) trunc(x) #endif @implementation ProgressBar - (instancetype)initWithLength: (unsigned long long)length resumedFrom: (unsigned long long)resumedFrom useUnicode: (bool)useUnicode { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); _useUnicode = useUnicode; _length = length; _resumedFrom = resumedFrom; _startDate = [[OFDate alloc] init]; _lastReceivedDate = [[OFDate alloc] init]; _drawTimer = [[OFTimer scheduledTimerWithTimeInterval: updateInterval target: self selector: @selector(draw) repeats: true] retain]; _BPSTimer = [[OFTimer scheduledTimerWithTimeInterval: 1.0 target: self selector: @selector( |
︙ | ︙ | |||
84 85 86 87 88 89 90 | } - (void)_drawProgress { float bars, percent; int columns, barWidth; | | > | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > | > > > | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | } - (void)_drawProgress { float bars, percent; int columns, barWidth; if ((columns = OFStdOut.columns) >= 0) { if (columns > 37) barWidth = columns - 37; else barWidth = 0; } else barWidth = 43; bars = (float)(_resumedFrom + _received) / (float)(_resumedFrom + _length) * barWidth; percent = (float)(_resumedFrom + _received) / (float)(_resumedFrom + _length) * 100; if (_useUnicode) { [OFStdOut writeString: @"\r ▕"]; for (size_t i = 0; i < (size_t)bars; i++) [OFStdOut writeString: @"█"]; if (bars < barWidth) { float rem = bars - truncf(bars); if (rem >= 0.875) [OFStdOut writeString: @"▉"]; else if (rem >= 0.75) [OFStdOut writeString: @"▊"]; else if (rem >= 0.625) [OFStdOut writeString: @"▋"]; else if (rem >= 0.5) [OFStdOut writeString: @"▌"]; else if (rem >= 0.375) [OFStdOut writeString: @"▍"]; else if (rem >= 0.25) [OFStdOut writeString: @"▎"]; else if (rem >= 0.125) [OFStdOut writeString: @"▏"]; else [OFStdOut writeString: @" "]; for (size_t i = 0; i < barWidth - (size_t)bars - 1; i++) [OFStdOut writeString: @" "]; } [OFStdOut writeFormat: @"▏ %,6.2f%% ", percent]; } else { [OFStdOut writeString: @"\r ["]; for (size_t i = 0; i < (size_t)bars; i++) [OFStdOut writeString: @"#"]; if (bars < barWidth) { float rem = bars - truncf(bars); if (rem >= 0.75) [OFStdOut writeString: @"O"]; else if (rem >= 0.5) [OFStdOut writeString: @"o"]; else if (rem >= 0.25) [OFStdOut writeString: @"."]; else [OFStdOut writeString: @" "]; for (size_t i = 0; i < barWidth - (size_t)bars - 1; i++) [OFStdOut writeString: @" "]; } [OFStdOut writeFormat: @"] %,6.2f%% ", percent]; } if (percent == 100) { double timeInterval = -_startDate.timeIntervalSinceNow; _BPS = (float)_received / (float)timeInterval; _ETA = timeInterval; } if (isinf(_ETA)) [OFStdOut writeString: @"--:--:-- "]; else if (_ETA >= 99 * 3600) { OFString *num = [OFString stringWithFormat: @"%,4.2f", _ETA / (24 * 3600)]; [OFStdOut writeString: OF_LOCALIZED(@"eta_days", @"%[num] d ", @"num", num)]; } else [OFStdOut writeFormat: @"%2u:%02u:%02u ", (uint8_t)(_ETA / 3600), (uint8_t)(_ETA / 60) % 60, (uint8_t)_ETA % 60]; if (_BPS >= oneGibibyte) { OFString *num = [OFString stringWithFormat: @"%,7.2f", _BPS / oneGibibyte]; [OFStdOut writeString: OF_LOCALIZED(@"progress_gibs", @"%[num] GiB/s", @"num", num)]; } else if (_BPS >= oneMebibyte) { OFString *num = [OFString stringWithFormat: @"%,7.2f", _BPS / oneMebibyte]; [OFStdOut writeString: OF_LOCALIZED(@"progress_mibs", @"%[num] MiB/s", @"num", num)]; } else if (_BPS >= oneKibibyte) { OFString *num = [OFString stringWithFormat: @"%,7.2f", _BPS / oneKibibyte]; [OFStdOut writeString: OF_LOCALIZED(@"progress_kibs", @"%[num] KiB/s", @"num", num)]; } else { OFString *num = [OFString stringWithFormat: @"%,7.2f", _BPS]; [OFStdOut writeString: OF_LOCALIZED(@"progress_bps", @"%[num] B/s ", @"num", num)]; } } - (void)_drawReceived { [OFStdOut writeString: @"\r "]; if (_resumedFrom + _received >= oneGibibyte) { OFString *num = [OFString stringWithFormat: @"%,7.2f", (float)(_resumedFrom + _received) / oneGibibyte]; [OFStdOut writeString: OF_LOCALIZED(@"progress_gib", @"%[num] GiB", @"num", num)]; } else if (_resumedFrom + _received >= oneMebibyte) { OFString *num = [OFString stringWithFormat: @"%,7.2f", (float)(_resumedFrom + _received) / oneMebibyte]; [OFStdOut writeString: OF_LOCALIZED(@"progress_mib", @"%[num] MiB", @"num", num)]; } else if (_resumedFrom + _received >= oneKibibyte) { OFString *num = [OFString stringWithFormat: @"%,7.2f", (float)(_resumedFrom + _received) / oneKibibyte]; [OFStdOut writeString: OF_LOCALIZED(@"progress_kib", @"%[num] KiB", @"num", num)]; } else { OFString *num = [OFString stringWithFormat: @"%jd", _resumedFrom + _received]; [OFStdOut writeString: OF_LOCALIZED(@"progress_bytes", @"[" @" [" @" {'num == 1': '1 byte '}," @" {'': '%[num] bytes'}" @" ]" @"]".objectByParsingJSON, @"num", num)]; } [OFStdOut writeString: @" "]; if (_stopped) _BPS = (float)_received / -(float)_startDate.timeIntervalSinceNow; if (_BPS >= oneGibibyte) { OFString *num = [OFString stringWithFormat: @"%,7.2f", _BPS / oneGibibyte]; [OFStdOut writeString: OF_LOCALIZED(@"progress_gibs", @"%[num] GiB/s", @"num", num)]; } else if (_BPS >= oneMebibyte) { OFString *num = [OFString stringWithFormat: @"%,7.2f", _BPS / oneMebibyte]; [OFStdOut writeString: OF_LOCALIZED(@"progress_mibs", @"%[num] MiB/s", @"num", num)]; } else if (_BPS >= oneKibibyte) { OFString *num = [OFString stringWithFormat: @"%,7.2f", _BPS / oneKibibyte]; [OFStdOut writeString: OF_LOCALIZED(@"progress_kibs", @"%[num] KiB/s", @"num", num)]; } else { OFString *num = [OFString stringWithFormat: @"%,7.2f", _BPS]; [OFStdOut writeString: OF_LOCALIZED(@"progress_bps", @"%[num] B/s ", @"num", num)]; } } - (void)draw { |
︙ | ︙ |
Modified utils/ofhttp/lang/de.json from [ad71562e8d] to [027af9bd4c].
︙ | ︙ | |||
48 49 50 51 52 53 54 | "%[prog]: Fehler beim Download von <%[url]>!\n", " Verbindung fehlgeschlagen: %[exception]" ], "download_failed_invalid_server_reply": [ "%[prog]: Fehler beim Download von <%[url]>!\n", " Ungültige Antwort vom Server!" ], | | | | | | > > | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | "%[prog]: Fehler beim Download von <%[url]>!\n", " Verbindung fehlgeschlagen: %[exception]" ], "download_failed_invalid_server_reply": [ "%[prog]: Fehler beim Download von <%[url]>!\n", " Ungültige Antwort vom Server!" ], "no_tls_support": [ "%[prog]: Keine TLS-Unterstützung in ObjFW!\n", " Um via HTTPS runterzuladen, müssen Sie entweder ObjFW mit TLS-", "Unterstützung\n", " kompilieren oder eine Bibliothek mittels „preoad” laden, welche ", "TLS-Support\n", " zu ObjFW hinzufügt!" ], "download_failed_read_or_write_failed_any": "Lesen oder Schreiben", "download_failed_read_or_write_failed_read": "Lesen", "download_failed_read_or_write_failed_write": "Schreiben", "download_failed_read_or_write_failed": [ "%[prog]: Fehler beim Download von <%[url]>!\n", " %[error]: %[exception]" |
︙ | ︙ |
Deleted utils/ofsock/Makefile version [0438ba0691].
|
| < < < < < < < < < < < < < < < < < < < < |
Deleted utils/ofsock/OFSock.m version [9ce3b460c5].
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |