mirror of
https://codeberg.org/libreboot/UEFITool.git
synced 2025-07-04 16:27:01 +00:00
Compare commits
No commits in common. "new_engine" and "A66" have entirely different histories.
new_engine
...
A66
192 changed files with 8864 additions and 35619 deletions
162
.github/workflows/main.yml
vendored
162
.github/workflows/main.yml
vendored
|
@ -11,7 +11,7 @@ jobs:
|
||||||
# Release builds
|
# Release builds
|
||||||
build_release_macos:
|
build_release_macos:
|
||||||
name: Release build (macOS universal, static Qt 6.5.0)
|
name: Release build (macOS universal, static Qt 6.5.0)
|
||||||
runs-on: macos-latest
|
runs-on: macos-12
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Get Qt
|
- name: Get Qt
|
||||||
|
@ -35,48 +35,26 @@ jobs:
|
||||||
run: cmake --build . --config Release
|
run: cmake --build . --config Release
|
||||||
- name: Create dist directory
|
- name: Create dist directory
|
||||||
run: cmake -E make_directory ${{runner.workspace}}/UEFITool/dist
|
run: cmake -E make_directory ${{runner.workspace}}/UEFITool/dist
|
||||||
- name: Signed archive everything
|
|
||||||
if: github.repository_owner == 'LongSoft'
|
|
||||||
working-directory: ${{runner.workspace}}/build
|
|
||||||
env:
|
|
||||||
MAC_CERTIFICATE_PASSWORD: ${{ secrets.MAC_CERTIFICATE_PASSWORD }}
|
|
||||||
MAC_ACCOUNT_NAME: ${{ secrets.MAC_ACCOUNT_NAME }}
|
|
||||||
MAC_ACCOUNT_PASSWORD: ${{ secrets.MAC_ACCOUNT_PASSWORD }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
UEFITOOL_VER=$(cat ../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \
|
|
||||||
codesign -fs - UEFIExtract/UEFIExtract
|
|
||||||
codesign -fs - UEFIFind/UEFIFind
|
|
||||||
zip -qryj ../UEFITool/dist/UEFIExtract_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFIExtract/UEFIExtract
|
|
||||||
zip -qryj ../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFIFind/UEFIFind
|
|
||||||
brew install create-dmg || exit 1
|
|
||||||
curl -OL "https://github.com/acidanthera/ocbuild/raw/master/codesign/appsign.sh" || exit 1
|
|
||||||
chmod a+x appsign.sh || exit 1
|
|
||||||
"$(pwd)/appsign.sh" ./UEFITool/UEFITool.app ../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_universal_mac.dmg
|
|
||||||
- name: Archive everything
|
- name: Archive everything
|
||||||
if: github.repository_owner != 'LongSoft'
|
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
UEFITOOL_VER=$(cat ../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \
|
UEFITOOL_VER=$(cat ../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \
|
||||||
codesign -fs - UEFIExtract/UEFIExtract
|
|
||||||
codesign -fs - UEFIFind/UEFIFind
|
|
||||||
zip -qryj ../UEFITool/dist/UEFIExtract_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFIExtract/UEFIExtract
|
zip -qryj ../UEFITool/dist/UEFIExtract_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFIExtract/UEFIExtract
|
||||||
zip -qryj ../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFIFind/UEFIFind
|
zip -qryj ../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFIFind/UEFIFind
|
||||||
cd UEFITool
|
cd UEFITool
|
||||||
codesign -fs - --deep UEFITool.app
|
|
||||||
zip -qry ../../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFITool.app
|
zip -qry ../../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_universal_mac.zip ./UEFITool.app
|
||||||
- name: Upload to artifacts
|
- name: Upload to artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: macOS builds
|
name: macOS builds
|
||||||
path: dist/*
|
path: dist/*.zip
|
||||||
- name: Upload to releases
|
- name: Upload to releases
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
uses: svenstaro/upload-release-action@v2
|
uses: svenstaro/upload-release-action@v2
|
||||||
with:
|
with:
|
||||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
file: dist/*
|
file: dist/*.zip
|
||||||
tag: ${{ github.ref }}
|
tag: ${{ github.ref }}
|
||||||
file_glob: true
|
file_glob: true
|
||||||
|
|
||||||
|
@ -109,7 +87,7 @@ jobs:
|
||||||
zip -qryj ../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_x64_linux.zip ./UEFIFind/uefifind
|
zip -qryj ../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_x64_linux.zip ./UEFIFind/uefifind
|
||||||
zip -qryj ../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_x64_linux.zip ./UEFITool/uefitool
|
zip -qryj ../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_x64_linux.zip ./UEFITool/uefitool
|
||||||
- name: Upload to artifacts
|
- name: Upload to artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: Linux builds
|
name: Linux builds
|
||||||
path: dist/*.zip
|
path: dist/*.zip
|
||||||
|
@ -124,18 +102,17 @@ jobs:
|
||||||
|
|
||||||
build_release_freebsd:
|
build_release_freebsd:
|
||||||
name: Release build (FreeBSD x64, shared Qt 6)
|
name: Release build (FreeBSD x64, shared Qt 6)
|
||||||
runs-on: ubuntu-latest
|
runs-on: macos-12
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Build on FreeBSD inside Ubuntu VM
|
- name: Build on FreeBSD inside macOS VM
|
||||||
id: test
|
id: test
|
||||||
uses: cross-platform-actions/action@v0.27.0
|
uses: vmactions/freebsd-vm@v0
|
||||||
with:
|
with:
|
||||||
operating_system: freebsd
|
usesh: true
|
||||||
version: '13.3'
|
prepare: |
|
||||||
shell: sh
|
pkg install -y zip cmake qt6-base
|
||||||
run: |
|
run: |
|
||||||
sudo pkg install -y zip cmake qt6-base
|
|
||||||
mkdir dist
|
mkdir dist
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
|
@ -146,7 +123,7 @@ jobs:
|
||||||
zip -qryj ../dist/UEFIFind_NE_${UEFITOOL_VER}_x64_freebsd.zip ./UEFIFind/uefifind
|
zip -qryj ../dist/UEFIFind_NE_${UEFITOOL_VER}_x64_freebsd.zip ./UEFIFind/uefifind
|
||||||
zip -qryj ../dist/UEFITool_NE_${UEFITOOL_VER}_x64_freebsd.zip ./UEFITool/uefitool
|
zip -qryj ../dist/UEFITool_NE_${UEFITOOL_VER}_x64_freebsd.zip ./UEFITool/uefitool
|
||||||
- name: Upload to artifacts
|
- name: Upload to artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: FreeBSD builds
|
name: FreeBSD builds
|
||||||
path: dist/*.zip
|
path: dist/*.zip
|
||||||
|
@ -182,7 +159,7 @@ jobs:
|
||||||
- name: Configure UEFIExtract
|
- name: Configure UEFIExtract
|
||||||
shell: bash
|
shell: bash
|
||||||
working-directory: ${{runner.workspace}}/build/UEFIExtract
|
working-directory: ${{runner.workspace}}/build/UEFIExtract
|
||||||
run: cmake -G "Visual Studio 16 2019" -A Win32 -T "v141_xp" -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" ../../UEFITool/UEFIExtract/
|
run: cmake -G "Visual Studio 16 2019" -T "v141_xp" ../../UEFITool/UEFIExtract/
|
||||||
- name: Build UEFIExtract
|
- name: Build UEFIExtract
|
||||||
working-directory: ${{runner.workspace}}/build/UEFIExtract
|
working-directory: ${{runner.workspace}}/build/UEFIExtract
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -198,7 +175,7 @@ jobs:
|
||||||
- name: Configure UEFIFind
|
- name: Configure UEFIFind
|
||||||
working-directory: ${{runner.workspace}}/build/UEFIFind
|
working-directory: ${{runner.workspace}}/build/UEFIFind
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cmake -G "Visual Studio 16 2019" -A Win32 -T "v141_xp" -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" ../../UEFITool/UEFIFind/
|
run: cmake -G "Visual Studio 16 2019" -T "v141_xp" ../../UEFITool/UEFIFind/
|
||||||
- name: Build UEFIFind
|
- name: Build UEFIFind
|
||||||
working-directory: ${{runner.workspace}}/build/UEFIFind
|
working-directory: ${{runner.workspace}}/build/UEFIFind
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -228,7 +205,7 @@ jobs:
|
||||||
UEFITOOL_VER=$(cat ../../../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \
|
UEFITOOL_VER=$(cat ../../../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \
|
||||||
7z a ../../../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_win32.zip UEFITool.exe
|
7z a ../../../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_win32.zip UEFITool.exe
|
||||||
- name: Upload to artifacts
|
- name: Upload to artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: Windows 32-bit builds
|
name: Windows 32-bit builds
|
||||||
path: dist/*.zip
|
path: dist/*.zip
|
||||||
|
@ -261,7 +238,7 @@ jobs:
|
||||||
- name: Configure everything
|
- name: Configure everything
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: cmake -DCMAKE_PREFIX_PATH="D:\a\UEFITool\qt-6.5.0-static-x64-msvc2022" -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" -A x64 ../UEFITool
|
run: cmake -DCMAKE_PREFIX_PATH="D:\a\UEFITool\qt-6.5.0-static-x64-msvc2022" -DCMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded" ../UEFITool
|
||||||
- name: Build everything
|
- name: Build everything
|
||||||
working-directory: ${{runner.workspace}}/build
|
working-directory: ${{runner.workspace}}/build
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -277,7 +254,7 @@ jobs:
|
||||||
7z a ../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_win64.zip ./UEFIFind/Release/UEFIFind.exe
|
7z a ../UEFITool/dist/UEFIFind_NE_${UEFITOOL_VER}_win64.zip ./UEFIFind/Release/UEFIFind.exe
|
||||||
7z a ../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_win64.zip ./UEFITool/Release/UEFITool.exe
|
7z a ../UEFITool/dist/UEFITool_NE_${UEFITOOL_VER}_win64.zip ./UEFITool/Release/UEFITool.exe
|
||||||
- name: Upload to artifacts
|
- name: Upload to artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: Windows 64-bit builds
|
name: Windows 64-bit builds
|
||||||
path: dist/*.zip
|
path: dist/*.zip
|
||||||
|
@ -322,34 +299,6 @@ jobs:
|
||||||
cmake -G "MinGW Makefiles" -B build .
|
cmake -G "MinGW Makefiles" -B build .
|
||||||
cmake --build build --parallel
|
cmake --build build --parallel
|
||||||
|
|
||||||
build_test_linux_fuzzer:
|
|
||||||
name: Fuzzer build test (Clang, Linux x64)
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Create build directory
|
|
||||||
run: cmake -E make_directory ${{runner.workspace}}/build
|
|
||||||
- name: Configure everything
|
|
||||||
working-directory: ${{runner.workspace}}/build
|
|
||||||
run: CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake ../UEFITool/fuzzing
|
|
||||||
- name: Build everything
|
|
||||||
working-directory: ${{runner.workspace}}/build
|
|
||||||
shell: bash
|
|
||||||
run: cmake --build .
|
|
||||||
- name: Create dist directory
|
|
||||||
run: cmake -E make_directory ${{runner.workspace}}/dist
|
|
||||||
- name: Archive everything
|
|
||||||
working-directory: ${{runner.workspace}}/build
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
UEFITOOL_VER=$(cat ../UEFITool/version.h | grep PROGRAM_VERSION | cut -d'"' -f2 | sed 's/NE alpha /A/') ; \
|
|
||||||
zip -qryj ../dist/ffsparser_fuzzer_NE_${UEFITOOL_VER}_x64_linux.zip ./ffsparser_fuzzer
|
|
||||||
- name: Upload to artifacts
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: Fuzzer
|
|
||||||
path: ${{runner.workspace}}/dist/*.zip
|
|
||||||
|
|
||||||
# Static Analysis
|
# Static Analysis
|
||||||
build_analyze_linux_coverity:
|
build_analyze_linux_coverity:
|
||||||
env:
|
env:
|
||||||
|
@ -380,11 +329,56 @@ jobs:
|
||||||
COVERITY_SCAN_EMAIL: ${{ secrets.COVERITY_SCAN_EMAIL }}
|
COVERITY_SCAN_EMAIL: ${{ secrets.COVERITY_SCAN_EMAIL }}
|
||||||
COVERITY_BUILD_COMMAND: cmake --build .
|
COVERITY_BUILD_COMMAND: cmake --build .
|
||||||
|
|
||||||
|
build_analyze_linux_pvs_studio_and_codeql:
|
||||||
|
if: github.repository_owner == 'LongSoft' && github.event_name != 'pull_request'
|
||||||
|
name: PVS-Studio and CodeQL Static Analysis (shared Qt 6.5.0)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Install Qt
|
||||||
|
uses: jurplel/install-qt-action@v3
|
||||||
|
with:
|
||||||
|
version: '6.5.0'
|
||||||
|
host: 'linux'
|
||||||
|
target: 'desktop'
|
||||||
|
- name: Install PVS-Studio
|
||||||
|
run: |
|
||||||
|
wget -q -O - https://files.pvs-studio.com/etc/pubkey.txt \
|
||||||
|
| sudo apt-key add -
|
||||||
|
sudo wget -O /etc/apt/sources.list.d/viva64.list \
|
||||||
|
https://files.pvs-studio.com/etc/viva64.list
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install pvs-studio
|
||||||
|
pvs-studio-analyzer credentials ${{ secrets.PVS_STUDIO_CREDENTIALS }}
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
languages: cpp
|
||||||
|
- name: Build everything
|
||||||
|
run: |
|
||||||
|
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=On -B build .
|
||||||
|
cmake --build build
|
||||||
|
- name: Perform CodeQL analysis
|
||||||
|
uses: github/codeql-action/analyze@v2
|
||||||
|
- name: Perform PVS-Studio analysis
|
||||||
|
run: |
|
||||||
|
pvs-studio-analyzer analyze -f build/compile_commands.json -j
|
||||||
|
- name: Convert PVS-Studio report
|
||||||
|
run: |
|
||||||
|
plog-converter -t sarif -o pvs-report.sarif PVS-Studio.log
|
||||||
|
- name: Publish PVS-Studio report
|
||||||
|
uses: github/codeql-action/upload-sarif@v2
|
||||||
|
with:
|
||||||
|
sarif_file: pvs-report.sarif
|
||||||
|
category: PVS-Studio
|
||||||
|
|
||||||
build_analyze_linux_sonarcloud:
|
build_analyze_linux_sonarcloud:
|
||||||
if: github.repository_owner == 'LongSoft' && github.event_name != 'pull_request'
|
if: github.repository_owner == 'LongSoft' && github.event_name != 'pull_request'
|
||||||
name: SonarCloud Static Analysis (shared Qt 6.5.0)
|
name: SonarCloud Static Analysis (shared Qt 6.5.0)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
|
SONAR_SCANNER_VERSION: 4.7.0.2747
|
||||||
|
SONAR_SERVER_URL: "https://sonarcloud.io"
|
||||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
@ -396,23 +390,33 @@ jobs:
|
||||||
version: '6.5.0'
|
version: '6.5.0'
|
||||||
host: 'linux'
|
host: 'linux'
|
||||||
target: 'desktop'
|
target: 'desktop'
|
||||||
- name: Install JDK 17
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
java-version: 17
|
java-version: 11
|
||||||
- name: Install build-wrapper
|
- name: Download and set up sonar-scanner
|
||||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
env:
|
||||||
|
SONAR_SCANNER_DOWNLOAD_URL: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${{ env.SONAR_SCANNER_VERSION }}-linux.zip
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/.sonar
|
||||||
|
curl -sSLo $HOME/.sonar/sonar-scanner.zip ${{ env.SONAR_SCANNER_DOWNLOAD_URL }}
|
||||||
|
unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
|
||||||
|
echo "$HOME/.sonar/sonar-scanner-${{ env.SONAR_SCANNER_VERSION }}-linux/bin" >> $GITHUB_PATH
|
||||||
|
- name: Download and set up build-wrapper
|
||||||
|
env:
|
||||||
|
BUILD_WRAPPER_DOWNLOAD_URL: ${{ env.SONAR_SERVER_URL }}/static/cpp/build-wrapper-linux-x86.zip
|
||||||
|
run: |
|
||||||
|
curl -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip ${{ env.BUILD_WRAPPER_DOWNLOAD_URL }}
|
||||||
|
unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/
|
||||||
|
echo "$HOME/.sonar/build-wrapper-linux-x86" >> $GITHUB_PATH
|
||||||
- name: Run build-wrapper
|
- name: Run build-wrapper
|
||||||
run: |
|
run: |
|
||||||
cmake -B build .
|
cmake -B build .
|
||||||
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||||
- name: SonarQube Scan
|
- name: Run sonar-scanner
|
||||||
uses: SonarSource/sonarqube-scan-action@v4.2.1
|
|
||||||
env:
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||||
SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }}
|
run: |
|
||||||
with:
|
sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||||
# Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options
|
|
||||||
args: >
|
|
||||||
--define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json"
|
|
||||||
|
|
18
README.md
18
README.md
|
@ -29,7 +29,7 @@ The missing parts are in development and the version with a new engine will be m
|
||||||
|
|
||||||
There are some other projects that use UEFITool's engine:
|
There are some other projects that use UEFITool's engine:
|
||||||
* UEFIExtract, which uses ffsParser to parse supplied firmware image into a tree structure and dumps the parsed structure recursively on the FS. Jethro Beekman's [tree](https://github.com/jethrogb/uefireverse) utility can be used to work with the extracted tree.
|
* UEFIExtract, which uses ffsParser to parse supplied firmware image into a tree structure and dumps the parsed structure recursively on the FS. Jethro Beekman's [tree](https://github.com/jethrogb/uefireverse) utility can be used to work with the extracted tree.
|
||||||
* UEFIFind, which uses ffsParser to find image elements containing a specified pattern. It was developed for [UBU](https://winraid.level1techs.com/t/tool-guide-news-uefi-bios-updater-ubu/30357) project.
|
* UEFIFind, which uses ffsParser to find image elements containing a specified pattern. It was developed for [UBU](http://www.win-raid.com/t154f16-Tool-Guide-News-quot-UEFI-BIOS-Updater-quot-UBU.html) project.
|
||||||
|
|
||||||
## Alternatives
|
## Alternatives
|
||||||
|
|
||||||
|
@ -42,24 +42,18 @@ Right now there are some alternatives to UEFITool that you could find useful too
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
You can either use [pre-built binaries](https://github.com/LongSoft/UEFITool/releases) or build a binary yourself.
|
You can either use [pre-built binaries for Windows and macOS](https://github.com/LongSoft/UEFITool/releases) or build a binary yourself.
|
||||||
* To build a binary that uses Qt library (UEFITool) you need a C++ compiler and an instance of [Qt5 or Qt6](https://www.qt.io) library. Install both of them, get the sources, generate makefiles using qmake (`qmake ./UEFITool/uefitool.pro`) and use your system's make command on that generated files (i.e. `nmake release`, `make release` and so on). Qt6-based builds can also use CMAKE as an altearnative build system.
|
* To build a binary that uses Qt library (UEFITool) you need a C++ compiler and an instance of [Qt5 or Qt6](https://www.qt.io) library. Install both of them, get the sources, generate makefiles using qmake (`qmake ./UEFITool/uefitool.pro`) and use your system's make command on that generated files (i.e. `nmake release`, `make release` and so on). Qt6-based builds can also use CMAKE as an altearnative build system.
|
||||||
* To build a binary that doesn't use Qt (UEFIExtract, UEFIFind), you need a C++ compiler and [CMAKE](https://cmake.org) utility to generate a makefile for your OS and build environment. Install both of them, get the sources, generate makefiles using cmake (`cmake UEFIExtract`) and use your system's make command on that generated files (i.e. `nmake release`, `make release` and so on). Non-Qt builds can also use Meson as an alternative build system.
|
* To build a binary that doesn't use Qt (UEFIExtract, UEFIFind), you need a C++ compiler and [CMAKE](https://cmake.org) utility to generate a makefile for your OS and build environment. Install both of them, get the sources, generate makefiles using cmake (`cmake UEFIExtract`) and use your system's make command on that generated files (i.e. `nmake release`, `make release` and so on). Non-Qt builds can also use Meson as an alternative build system.
|
||||||
|
|
||||||
## Known issues
|
## Known issues
|
||||||
|
* Image editing is currently only possible using an outdated and unsupported UEFITool 0.28 (`old_engine` branch) and the tools based on it (`UEFIReplace`, `UEFIPatch`). This is the top priority issue #67, which is being worked on, albeit slowly (due to the amount of coding and testing required to implement it correctly).
|
||||||
* Image editing is currently only possible using an outdated and unsupported UEFITool 0.28 (`old_engine` branch) and the tools based on it (`UEFIReplace`, `UEFIPatch`). This is the top priority [issue #67](https://github.com/LongSoft/UEFITool/issues/67), which is being worked on, albeit slowly (due to the amount of coding and testing required to implement it correctly).
|
|
||||||
* Some vendor-specific firmware update files can be opened incorrectly or can't be opened at all. This includes encrypted HP update files, Dell HDR and EXE files, some InsydeFlash FD files and so on. Enabling support for such files will require massive amount of reverse-engineering which is almost pointless because the updated image can be obtained from BIOS chip where it's already decrypted and unpacked.
|
* Some vendor-specific firmware update files can be opened incorrectly or can't be opened at all. This includes encrypted HP update files, Dell HDR and EXE files, some InsydeFlash FD files and so on. Enabling support for such files will require massive amount of reverse-engineering which is almost pointless because the updated image can be obtained from BIOS chip where it's already decrypted and unpacked.
|
||||||
* Intel Firmware Interface Table (FIT) editing is not supported right now. FIT contains pointers to various image components that must be loaded before executing the first CPU instruction from the BIOS chip. Those components include CPU microcode updates, binaries and settings used by BIOS Guard and Boot Guard technologies and some other stuff. More information on FIT can be obtained [here](https://edc.intel.com/content/www/us/en/design/products-and-solutions/software-and-services/firmware-and-bios/firmware-interface-table/firmware-interface-table/).
|
* Intel Firmware Interface Table (FIT) editing is not supported right now. FIT contains pointers to various image components that must be loaded before executing the first CPU instruction from the BIOS chip. Those components include CPU microcode updates, binaries and settings used by BIOS Guard and Boot Guard technologies and some other stuff. More information on FIT can be obtained [here](https://edc.intel.com/content/www/us/en/design/products-and-solutions/software-and-services/firmware-and-bios/firmware-interface-table/firmware-interface-table/).
|
||||||
* Windows builds of `UEFIExtract` and `UEFIFind` might encouter an issue with folder paths being longer than 260 bytes (`MAX_PATH`) on some input files (see [issue #363](https://github.com/LongSoft/UEFITool/issues/363)). This is a [known Windows limitation](https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry), that can be fixed by enabling long paths support via Windows Registry and adding a manifest to the executable file that requires such support. `UEFIExtract` has the required manifest additions since version `A67`, and the required registry file is provided by Microsoft on the page linked above, but this workaround is only awailable starting with Windows 10 build 1067.
|
|
||||||
|
|
||||||
## Bug repellents
|
## Bug repellents
|
||||||
|
|
||||||
* [Coverity Scan](https://scan.coverity.com/projects/17209) - static analyzer for C, C++, C#, JavaScript, Ruby, or Python code.
|
* [Coverity Scan](https://scan.coverity.com/projects/17209) - static analyzer for C, C++, C#, JavaScript, Ruby, or Python code.
|
||||||
* [SonarCloud](https://sonarcloud.io/project/overview?id=LongSoft_UEFITool) - cloud-based source code analysis service.
|
* [SonarCloud](https://sonarcloud.io/project/overview?id=LongSoft_UEFITool) - cloud-based code analysis service.
|
||||||
|
* [PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=github&utm_medium=organic&utm_campaign=open_source) - static analyzer for C, C++, C#, and Java code.
|
||||||
|
* [CodeQL](https://codeql.github.com/docs/codeql-overview/about-codeql) - code analysis engine developed by GitHub to automate security checks.
|
||||||
|
|
||||||
## GUID Database
|
|
||||||
|
|
||||||
Every new release includes an update to the database of known UEFI-related GUIDs build with help of [Linux Vendor Firmware Service](https://fwupd.org).
|
|
||||||
|
|
||||||
You can download the up-to-date version of that database using [this link](https://fwupd.org/lvfs/shards/export/csv).
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.22)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.1.0 FATAL_ERROR)
|
||||||
|
|
||||||
PROJECT(UEFIExtract)
|
PROJECT(UEFIExtract)
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ SET(PROJECT_SOURCES
|
||||||
uefidump.cpp
|
uefidump.cpp
|
||||||
../common/guiddatabase.cpp
|
../common/guiddatabase.cpp
|
||||||
../common/types.cpp
|
../common/types.cpp
|
||||||
../common/filesystem.cpp
|
|
||||||
../common/descriptor.cpp
|
../common/descriptor.cpp
|
||||||
../common/ffs.cpp
|
../common/ffs.cpp
|
||||||
../common/nvram.cpp
|
../common/nvram.cpp
|
||||||
|
@ -35,17 +34,6 @@ SET(PROJECT_SOURCES
|
||||||
../common/bstrlib/bstrlib.c
|
../common/bstrlib/bstrlib.c
|
||||||
../common/bstrlib/bstrwrap.cpp
|
../common/bstrlib/bstrwrap.cpp
|
||||||
../common/generated/ami_nvar.cpp
|
../common/generated/ami_nvar.cpp
|
||||||
../common/generated/apple_sysf.cpp
|
|
||||||
../common/generated/dell_dvar.cpp
|
|
||||||
../common/generated/edk2_vss.cpp
|
|
||||||
../common/generated/edk2_vss2.cpp
|
|
||||||
../common/generated/edk2_ftw.cpp
|
|
||||||
../common/generated/insyde_fdc.cpp
|
|
||||||
../common/generated/insyde_fdm.cpp
|
|
||||||
../common/generated/ms_slic_marker.cpp
|
|
||||||
../common/generated/ms_slic_pubkey.cpp
|
|
||||||
../common/generated/phoenix_flm.cpp
|
|
||||||
../common/generated/phoenix_evsa.cpp
|
|
||||||
../common/generated/intel_acbp_v1.cpp
|
../common/generated/intel_acbp_v1.cpp
|
||||||
../common/generated/intel_acbp_v2.cpp
|
../common/generated/intel_acbp_v2.cpp
|
||||||
../common/generated/intel_keym_v1.cpp
|
../common/generated/intel_keym_v1.cpp
|
||||||
|
@ -73,14 +61,9 @@ SET(PROJECT_SOURCES
|
||||||
../common/zlib/zutil.c
|
../common/zlib/zutil.c
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_DEFINITIONS(
|
ADD_DEFINITIONS(-DU_ENABLE_NVRAM_PARSING_SUPPORT -DU_ENABLE_ME_PARSING_SUPPORT -DU_ENABLE_FIT_PARSING_SUPPORT -DU_ENABLE_GUID_DATABASE_SUPPORT)
|
||||||
-DU_ENABLE_NVRAM_PARSING_SUPPORT
|
|
||||||
-DU_ENABLE_ME_PARSING_SUPPORT
|
|
||||||
-DU_ENABLE_FIT_PARSING_SUPPORT
|
|
||||||
-DU_ENABLE_GUID_DATABASE_SUPPORT
|
|
||||||
)
|
|
||||||
|
|
||||||
ADD_EXECUTABLE(UEFIExtract ${PROJECT_SOURCES} uefiextract.manifest)
|
ADD_EXECUTABLE(UEFIExtract ${PROJECT_SOURCES})
|
||||||
|
|
||||||
IF(UNIX)
|
IF(UNIX)
|
||||||
SET_TARGET_PROPERTIES(UEFIExtract PROPERTIES OUTPUT_NAME uefiextract)
|
SET_TARGET_PROPERTIES(UEFIExtract PROPERTIES OUTPUT_NAME uefiextract)
|
||||||
|
|
|
@ -33,9 +33,8 @@ USTATUS FfsDumper::dump(const UModelIndex & root, const UString & path, const Du
|
||||||
printf("Error %zu returned from recursiveDump (directory \"%s\").\n", result, (const char*)path.toLocal8Bit());
|
printf("Error %zu returned from recursiveDump (directory \"%s\").\n", result, (const char*)path.toLocal8Bit());
|
||||||
return result;
|
return result;
|
||||||
} else if (!dumped) {
|
} else if (!dumped) {
|
||||||
if (removeDirectory(path)) {
|
removeDirectory(path);
|
||||||
printf("Removed directory \"%s\" since nothing was dumped.\n", (const char*)path.toLocal8Bit());
|
printf("Removed directory \"%s\" since nothing was dumped.\n", (const char*)path.toLocal8Bit());
|
||||||
}
|
|
||||||
return U_ITEM_NOT_FOUND;
|
return U_ITEM_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +58,7 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentPath != path) {
|
if (currentPath != path) {
|
||||||
counterHeader = counterBody = counterUncData = counterRaw = counterInfo = 0;
|
counterHeader = counterBody = counterRaw = counterInfo = 0;
|
||||||
currentPath = path;
|
currentPath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +67,7 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path
|
||||||
&& (sectionType == IgnoreSectionType || model->subtype(index) == sectionType)) {
|
&& (sectionType == IgnoreSectionType || model->subtype(index) == sectionType)) {
|
||||||
|
|
||||||
if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_HEADER)
|
if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_HEADER)
|
||||||
&& !model->hasEmptyHeader(index)) {
|
&& !model->header(index).isEmpty()) {
|
||||||
fileList.insert(index);
|
fileList.insert(index);
|
||||||
|
|
||||||
UString filename;
|
UString filename;
|
||||||
|
@ -91,7 +90,7 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_BODY)
|
if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_BODY)
|
||||||
&& !model->hasEmptyBody(index)) {
|
&& !model->body(index).isEmpty()) {
|
||||||
fileList.insert(index);
|
fileList.insert(index);
|
||||||
UString filename;
|
UString filename;
|
||||||
if (counterBody == 0)
|
if (counterBody == 0)
|
||||||
|
@ -112,28 +111,6 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path
|
||||||
dumped = true;
|
dumped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dumpMode == DUMP_ALL || dumpMode == DUMP_CURRENT || dumpMode == DUMP_UNC_DATA)
|
|
||||||
&& !model->hasEmptyUncompressedData(index)) {
|
|
||||||
fileList.insert(index);
|
|
||||||
UString filename;
|
|
||||||
if (counterUncData == 0)
|
|
||||||
filename = usprintf("%s/unc_data.bin", path.toLocal8Bit());
|
|
||||||
else
|
|
||||||
filename = usprintf("%s/unc_data_%d.bin", path.toLocal8Bit(), counterUncData);
|
|
||||||
counterUncData++;
|
|
||||||
|
|
||||||
std::ofstream file(filename.toLocal8Bit(), std::ofstream::binary);
|
|
||||||
if (!file) {
|
|
||||||
printf("Cannot open uncompressed data \"%s\".\n", (const char*)filename.toLocal8Bit());
|
|
||||||
return U_FILE_OPEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
const UByteArray &data = model->uncompressedData(index);
|
|
||||||
file.write(data.constData(), data.size());
|
|
||||||
|
|
||||||
dumped = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dumpMode == DUMP_FILE) {
|
if (dumpMode == DUMP_FILE) {
|
||||||
UModelIndex fileIndex = index;
|
UModelIndex fileIndex = index;
|
||||||
if (model->type(fileIndex) != Types::File) {
|
if (model->type(fileIndex) != Types::File) {
|
||||||
|
|
|
@ -30,7 +30,6 @@ public:
|
||||||
DUMP_CURRENT,
|
DUMP_CURRENT,
|
||||||
DUMP_ALL,
|
DUMP_ALL,
|
||||||
DUMP_BODY,
|
DUMP_BODY,
|
||||||
DUMP_UNC_DATA,
|
|
||||||
DUMP_HEADER,
|
DUMP_HEADER,
|
||||||
DUMP_INFO,
|
DUMP_INFO,
|
||||||
DUMP_FILE
|
DUMP_FILE
|
||||||
|
@ -39,7 +38,7 @@ public:
|
||||||
static const UINT8 IgnoreSectionType = 0xFF;
|
static const UINT8 IgnoreSectionType = 0xFF;
|
||||||
|
|
||||||
explicit FfsDumper(TreeModel * treeModel) : model(treeModel), dumped(false),
|
explicit FfsDumper(TreeModel * treeModel) : model(treeModel), dumped(false),
|
||||||
counterHeader(0), counterBody(0), counterUncData(0), counterRaw(0), counterInfo(0) {}
|
counterHeader(0), counterBody(0), counterRaw(0), counterInfo(0) {}
|
||||||
~FfsDumper() {};
|
~FfsDumper() {};
|
||||||
|
|
||||||
USTATUS dump(const UModelIndex & root, const UString & path, const DumpMode dumpMode = DUMP_CURRENT, const UINT8 sectionType = IgnoreSectionType, const UString & guid = UString());
|
USTATUS dump(const UModelIndex & root, const UString & path, const DumpMode dumpMode = DUMP_CURRENT, const UINT8 sectionType = IgnoreSectionType, const UString & guid = UString());
|
||||||
|
@ -49,7 +48,7 @@ private:
|
||||||
TreeModel* model;
|
TreeModel* model;
|
||||||
UString currentPath;
|
UString currentPath;
|
||||||
bool dumped;
|
bool dumped;
|
||||||
int counterHeader, counterBody, counterUncData, counterRaw, counterInfo;
|
int counterHeader, counterBody, counterRaw, counterInfo;
|
||||||
std::set<UModelIndex> fileList;
|
std::set<UModelIndex> fileList;
|
||||||
};
|
};
|
||||||
#endif // FFSDUMPER_H
|
#endif // FFSDUMPER_H
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
<assembly xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
|
||||||
<asmv1:assemblyIdentity type='win32' name='me.coderush.UEFIExtract' version='1.0.0.0' />
|
|
||||||
<asmv3:application>
|
|
||||||
<asmv3:windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
|
|
||||||
<ws2:longPathAware>true</ws2:longPathAware>
|
|
||||||
</asmv3:windowsSettings>
|
|
||||||
</asmv3:application>
|
|
||||||
</assembly>
|
|
|
@ -42,7 +42,7 @@ void print_usage()
|
||||||
<< " UEFIExtract imagefile guids - only generate GUID database, no dump or report needed." << std::endl
|
<< " UEFIExtract imagefile guids - only generate GUID database, no dump or report needed." << std::endl
|
||||||
<< " UEFIExtract imagefile GUID_1 ... [ -o FILE_1 ... ] [ -m MODE_1 ... ] [ -t TYPE_1 ... ] -" << std::endl
|
<< " UEFIExtract imagefile GUID_1 ... [ -o FILE_1 ... ] [ -m MODE_1 ... ] [ -t TYPE_1 ... ] -" << std::endl
|
||||||
<< " Dump only FFS file(s) with specific GUID(s), without report or GUID database." << std::endl
|
<< " Dump only FFS file(s) with specific GUID(s), without report or GUID database." << std::endl
|
||||||
<< " Type is section type or FF to ignore. Mode is one of: all, body, unc_data, header, info, file." << std::endl
|
<< " Type is section type or FF to ignore. Mode is one of: all, body, header, info, file." << std::endl
|
||||||
<< " Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise." << std::endl;
|
<< " Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,8 +72,9 @@ int main(int argc, char *argv[])
|
||||||
USTATUS result;
|
USTATUS result;
|
||||||
UByteArray buffer;
|
UByteArray buffer;
|
||||||
UString path = getAbsPath(argv[1]);
|
UString path = getAbsPath(argv[1]);
|
||||||
if (false == readFileIntoBuffer(path, buffer))
|
result = readFileIntoBuffer(path, buffer);
|
||||||
return U_FILE_OPEN;
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
// Hack to support legacy UEFIDump mode
|
// Hack to support legacy UEFIDump mode
|
||||||
if (argc == 3 && !std::strcmp(argv[2], "unpack")) {
|
if (argc == 3 && !std::strcmp(argv[2], "unpack")) {
|
||||||
|
@ -87,7 +88,7 @@ int main(int argc, char *argv[])
|
||||||
// Parse input buffer
|
// Parse input buffer
|
||||||
result = ffsParser.parse(buffer);
|
result = ffsParser.parse(buffer);
|
||||||
if (result)
|
if (result)
|
||||||
return (int)result;
|
return result;
|
||||||
|
|
||||||
ffsParser.outputInfo();
|
ffsParser.outputInfo();
|
||||||
|
|
||||||
|
@ -102,7 +103,7 @@ int main(int argc, char *argv[])
|
||||||
else if (argc == 3 && !std::strcmp(argv[2], "guids")) {
|
else if (argc == 3 && !std::strcmp(argv[2], "guids")) {
|
||||||
GuidDatabase db = guidDatabaseFromTreeRecursive(&model, model.index(0, 0));
|
GuidDatabase db = guidDatabaseFromTreeRecursive(&model, model.index(0, 0));
|
||||||
if (!db.empty()) {
|
if (!db.empty()) {
|
||||||
return (int)guidDatabaseExportToFile(path + UString(".guids.csv"), db);
|
return guidDatabaseExportToFile(path + UString(".guids.csv"), db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Generate report, no dump or GUID database
|
// Generate report, no dump or GUID database
|
||||||
|
@ -175,8 +176,6 @@ int main(int argc, char *argv[])
|
||||||
modes.push_back(FfsDumper::DUMP_ALL);
|
modes.push_back(FfsDumper::DUMP_ALL);
|
||||||
else if (!std::strcmp(arg, "body"))
|
else if (!std::strcmp(arg, "body"))
|
||||||
modes.push_back(FfsDumper::DUMP_BODY);
|
modes.push_back(FfsDumper::DUMP_BODY);
|
||||||
else if (!std::strcmp(arg, "unc_data"))
|
|
||||||
modes.push_back(FfsDumper::DUMP_UNC_DATA);
|
|
||||||
else if (!std::strcmp(arg, "header"))
|
else if (!std::strcmp(arg, "header"))
|
||||||
modes.push_back(FfsDumper::DUMP_HEADER);
|
modes.push_back(FfsDumper::DUMP_HEADER);
|
||||||
else if (!std::strcmp(arg, "info"))
|
else if (!std::strcmp(arg, "info"))
|
||||||
|
@ -210,7 +209,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)lastError;
|
return lastError;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If parameters are different, show version and usage information
|
// If parameters are different, show version and usage information
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.22)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.1.0 FATAL_ERROR)
|
||||||
|
|
||||||
PROJECT(UEFIFind)
|
PROJECT(UEFIFind)
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ SET(PROJECT_SOURCES
|
||||||
uefifind.cpp
|
uefifind.cpp
|
||||||
../common/guiddatabase.cpp
|
../common/guiddatabase.cpp
|
||||||
../common/types.cpp
|
../common/types.cpp
|
||||||
../common/filesystem.cpp
|
|
||||||
../common/descriptor.cpp
|
../common/descriptor.cpp
|
||||||
../common/ffs.cpp
|
../common/ffs.cpp
|
||||||
../common/nvram.cpp
|
../common/nvram.cpp
|
||||||
|
@ -32,17 +31,6 @@ SET(PROJECT_SOURCES
|
||||||
../common/bstrlib/bstrlib.c
|
../common/bstrlib/bstrlib.c
|
||||||
../common/bstrlib/bstrwrap.cpp
|
../common/bstrlib/bstrwrap.cpp
|
||||||
../common/generated/ami_nvar.cpp
|
../common/generated/ami_nvar.cpp
|
||||||
../common/generated/apple_sysf.cpp
|
|
||||||
../common/generated/dell_dvar.cpp
|
|
||||||
../common/generated/edk2_vss.cpp
|
|
||||||
../common/generated/edk2_vss2.cpp
|
|
||||||
../common/generated/edk2_ftw.cpp
|
|
||||||
../common/generated/insyde_fdc.cpp
|
|
||||||
../common/generated/insyde_fdm.cpp
|
|
||||||
../common/generated/ms_slic_marker.cpp
|
|
||||||
../common/generated/ms_slic_pubkey.cpp
|
|
||||||
../common/generated/phoenix_flm.cpp
|
|
||||||
../common/generated/phoenix_evsa.cpp
|
|
||||||
../common/generated/intel_acbp_v1.cpp
|
../common/generated/intel_acbp_v1.cpp
|
||||||
../common/generated/intel_acbp_v2.cpp
|
../common/generated/intel_acbp_v2.cpp
|
||||||
../common/generated/intel_keym_v1.cpp
|
../common/generated/intel_keym_v1.cpp
|
||||||
|
@ -70,7 +58,7 @@ SET(PROJECT_SOURCES
|
||||||
../common/zlib/zutil.c
|
../common/zlib/zutil.c
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_EXECUTABLE(UEFIFind ${PROJECT_SOURCES} uefifind.manifest)
|
ADD_EXECUTABLE(UEFIFind ${PROJECT_SOURCES})
|
||||||
|
|
||||||
IF(UNIX)
|
IF(UNIX)
|
||||||
SET_TARGET_PROPERTIES(UEFIFind PROPERTIES OUTPUT_NAME uefifind)
|
SET_TARGET_PROPERTIES(UEFIFind PROPERTIES OUTPUT_NAME uefifind)
|
||||||
|
|
|
@ -32,11 +32,13 @@ UEFIFind::~UEFIFind()
|
||||||
|
|
||||||
USTATUS UEFIFind::init(const UString & path)
|
USTATUS UEFIFind::init(const UString & path)
|
||||||
{
|
{
|
||||||
|
USTATUS result;
|
||||||
UByteArray buffer;
|
UByteArray buffer;
|
||||||
if (false == readFileIntoBuffer(path, buffer))
|
result = readFileIntoBuffer(path, buffer);
|
||||||
return U_FILE_OPEN;
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
USTATUS result = ffsParser->parse(buffer);
|
result = ffsParser->parse(buffer);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
<assembly xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
|
||||||
<asmv1:assemblyIdentity type='win32' name='me.coderush.UEFIFind' version='1.0.0.0' />
|
|
||||||
<asmv3:application>
|
|
||||||
<asmv3:windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
|
|
||||||
<ws2:longPathAware>true</ws2:longPathAware>
|
|
||||||
</asmv3:windowsSettings>
|
|
||||||
</asmv3:application>
|
|
||||||
</assembly>
|
|
|
@ -32,6 +32,8 @@ int main(int argc, char *argv[])
|
||||||
UEFIFind w;
|
UEFIFind w;
|
||||||
USTATUS result;
|
USTATUS result;
|
||||||
|
|
||||||
|
initGuidDatabase("guids.csv");
|
||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
print_usage();
|
print_usage();
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
|
|
|
@ -23,6 +23,7 @@ SET(PROJECT_HEADERS
|
||||||
hexviewdialog.h
|
hexviewdialog.h
|
||||||
gotobasedialog.h
|
gotobasedialog.h
|
||||||
gotoaddressdialog.h
|
gotoaddressdialog.h
|
||||||
|
qhexview5/qhexview.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(PROJECT_SOURCES
|
SET(PROJECT_SOURCES
|
||||||
|
@ -35,6 +36,19 @@ SET(PROJECT_SOURCES
|
||||||
hexlineedit.cpp
|
hexlineedit.cpp
|
||||||
ffsfinder.cpp
|
ffsfinder.cpp
|
||||||
hexspinbox.cpp
|
hexspinbox.cpp
|
||||||
|
qhexview5/model/buffer/qhexbuffer.cpp
|
||||||
|
qhexview5/model/buffer/qdevicebuffer.cpp
|
||||||
|
qhexview5/model/buffer/qmemorybuffer.cpp
|
||||||
|
qhexview5/model/commands/hexcommand.cpp
|
||||||
|
qhexview5/model/commands/insertcommand.cpp
|
||||||
|
qhexview5/model/commands/removecommand.cpp
|
||||||
|
qhexview5/model/commands/replacecommand.cpp
|
||||||
|
qhexview5/model/qhexcursor.cpp
|
||||||
|
qhexview5/model/qhexdelegate.cpp
|
||||||
|
qhexview5/model/qhexdocument.cpp
|
||||||
|
qhexview5/model/qhexmetadata.cpp
|
||||||
|
qhexview5/model/qhexutils.cpp
|
||||||
|
qhexview5/qhexview.cpp
|
||||||
../common/fitparser.cpp
|
../common/fitparser.cpp
|
||||||
../common/guiddatabase.cpp
|
../common/guiddatabase.cpp
|
||||||
../common/nvram.cpp
|
../common/nvram.cpp
|
||||||
|
@ -68,17 +82,6 @@ SET(PROJECT_SOURCES
|
||||||
../common/digest/sha512.c
|
../common/digest/sha512.c
|
||||||
../common/digest/sm3.c
|
../common/digest/sm3.c
|
||||||
../common/generated/ami_nvar.cpp
|
../common/generated/ami_nvar.cpp
|
||||||
../common/generated/apple_sysf.cpp
|
|
||||||
../common/generated/dell_dvar.cpp
|
|
||||||
../common/generated/edk2_vss.cpp
|
|
||||||
../common/generated/edk2_vss2.cpp
|
|
||||||
../common/generated/edk2_ftw.cpp
|
|
||||||
../common/generated/insyde_fdc.cpp
|
|
||||||
../common/generated/insyde_fdm.cpp
|
|
||||||
../common/generated/ms_slic_marker.cpp
|
|
||||||
../common/generated/ms_slic_pubkey.cpp
|
|
||||||
../common/generated/phoenix_evsa.cpp
|
|
||||||
../common/generated/phoenix_flm.cpp
|
|
||||||
../common/generated/intel_acbp_v1.cpp
|
../common/generated/intel_acbp_v1.cpp
|
||||||
../common/generated/intel_acbp_v2.cpp
|
../common/generated/intel_acbp_v2.cpp
|
||||||
../common/generated/intel_keym_v1.cpp
|
../common/generated/intel_keym_v1.cpp
|
||||||
|
@ -121,9 +124,6 @@ TARGET_INCLUDE_DIRECTORIES(UEFITool PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(UEFITool PRIVATE Qt6::Widgets)
|
TARGET_LINK_LIBRARIES(UEFITool PRIVATE Qt6::Widgets)
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(QHexView)
|
|
||||||
TARGET_LINK_LIBRARIES(UEFITool PRIVATE QHexView)
|
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(UEFITool PROPERTIES
|
SET_TARGET_PROPERTIES(UEFITool PROPERTIES
|
||||||
WIN32_EXECUTABLE ON
|
WIN32_EXECUTABLE ON
|
||||||
MACOSX_BUNDLE ON
|
MACOSX_BUNDLE ON
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>uefitool</string>
|
<string>uefitool</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>me.coderush.UEFITool</string>
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.13)
|
|
||||||
|
|
||||||
project(QHexView)
|
|
||||||
|
|
||||||
option(QHEXVIEW_BUILD_EXAMPLE "Build Example Application" OFF)
|
|
||||||
option(QHEXVIEW_USE_QT5 "Enable Qt5 build" OFF)
|
|
||||||
option(QHEXVIEW_ENABLE_DIALOGS "BuiltIn dialogs" OFF)
|
|
||||||
|
|
||||||
if(QHEXVIEW_USE_QT5)
|
|
||||||
find_package(Qt5 REQUIRED COMPONENTS Widgets)
|
|
||||||
else()
|
|
||||||
find_package(Qt6 COMPONENTS Widgets)
|
|
||||||
|
|
||||||
if(NOT Qt6_FOUND)
|
|
||||||
find_package(Qt5 REQUIRED COMPONENTS Widgets)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} STATIC)
|
|
||||||
|
|
||||||
set_target_properties(${PROJECT_NAME}
|
|
||||||
PROPERTIES
|
|
||||||
CXX_STANDARD_REQUIRED YES
|
|
||||||
CXX_STANDARD 11
|
|
||||||
AUTOMOC ON
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
|
||||||
PUBLIC
|
|
||||||
Qt::Widgets
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME}
|
|
||||||
PUBLIC
|
|
||||||
"${PROJECT_SOURCE_DIR}/include"
|
|
||||||
)
|
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME}
|
|
||||||
PRIVATE
|
|
||||||
include/QHexView/model/buffer/qdevicebuffer.h
|
|
||||||
include/QHexView/model/buffer/qhexbuffer.h
|
|
||||||
include/QHexView/model/buffer/qmappedfilebuffer.h
|
|
||||||
include/QHexView/model/buffer/qmemorybuffer.h
|
|
||||||
include/QHexView/model/buffer/qmemoryrefbuffer.h
|
|
||||||
include/QHexView/model/commands/hexcommand.h
|
|
||||||
include/QHexView/model/commands/insertcommand.h
|
|
||||||
include/QHexView/model/commands/removecommand.h
|
|
||||||
include/QHexView/model/commands/replacecommand.h
|
|
||||||
include/QHexView/model/commands/replacecommand.h
|
|
||||||
include/QHexView/model/qhexcursor.h
|
|
||||||
include/QHexView/model/qhexdelegate.h
|
|
||||||
include/QHexView/model/qhexdocument.h
|
|
||||||
include/QHexView/model/qhexmetadata.h
|
|
||||||
include/QHexView/model/qhexoptions.h
|
|
||||||
include/QHexView/model/qhexutils.h
|
|
||||||
include/QHexView/qhexview.h
|
|
||||||
|
|
||||||
PRIVATE
|
|
||||||
src/model/commands/hexcommand.cpp
|
|
||||||
src/model/commands/insertcommand.cpp
|
|
||||||
src/model/commands/removecommand.cpp
|
|
||||||
src/model/commands/replacecommand.cpp
|
|
||||||
src/model/buffer/qdevicebuffer.cpp
|
|
||||||
src/model/buffer/qhexbuffer.cpp
|
|
||||||
src/model/buffer/qmemorybuffer.cpp
|
|
||||||
src/model/buffer/qmemoryrefbuffer.cpp
|
|
||||||
src/model/buffer/qmappedfilebuffer.cpp
|
|
||||||
src/model/qhexdelegate.cpp
|
|
||||||
src/model/qhexutils.cpp
|
|
||||||
src/model/qhexcursor.cpp
|
|
||||||
src/model/qhexmetadata.cpp
|
|
||||||
src/model/qhexdocument.cpp
|
|
||||||
src/qhexview.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
if(QHEXVIEW_ENABLE_DIALOGS)
|
|
||||||
target_sources(${PROJECT_NAME}
|
|
||||||
PRIVATE
|
|
||||||
include/QHexView/dialogs/hexfinddialog.h
|
|
||||||
src/dialogs/hexfinddialog.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_definitions(${PROJECT_NAME}
|
|
||||||
PUBLIC
|
|
||||||
QHEXVIEW_ENABLE_DIALOGS
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(QHEXVIEW_BUILD_EXAMPLE)
|
|
||||||
add_subdirectory(example)
|
|
||||||
endif()
|
|
|
@ -1,56 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QHexView/model/qhexutils.h>
|
|
||||||
|
|
||||||
class QRegularExpressionValidator;
|
|
||||||
class QDoubleValidator;
|
|
||||||
class QIntValidator;
|
|
||||||
class QHexView;
|
|
||||||
|
|
||||||
class HexFindDialog: public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum class Type { Find, Replace };
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit HexFindDialog(HexFindDialog::Type type = Type::Find,
|
|
||||||
QHexView* parent = nullptr);
|
|
||||||
QHexView* hexView() const;
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void updateFindOptions(int);
|
|
||||||
void validateActions();
|
|
||||||
void replace();
|
|
||||||
void find();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool prepareOptions(QString& q, QHexFindMode& mode, QHexFindDirection& fd);
|
|
||||||
bool validateIntRange(uint v) const;
|
|
||||||
void checkResult(const QString& q, qint64 offset, QHexFindDirection fd);
|
|
||||||
void prepareTextMode(QLayout* l);
|
|
||||||
void prepareHexMode(QLayout* l);
|
|
||||||
void prepareIntMode(QLayout* l);
|
|
||||||
void prepareFloatMode(QLayout* l);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QRegularExpressionValidator *m_hexvalidator, *m_hexpvalidator;
|
|
||||||
QDoubleValidator* m_dblvalidator;
|
|
||||||
QIntValidator* m_intvalidator;
|
|
||||||
int m_oldidxbits{-1}, m_oldidxendian{-1};
|
|
||||||
unsigned int m_findoptions{0};
|
|
||||||
qint64 m_startoffset{-1};
|
|
||||||
Type m_type;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const QString BUTTONBOX;
|
|
||||||
static const QString CBFINDMODE;
|
|
||||||
static const QString LEFIND;
|
|
||||||
static const QString LEREPLACE;
|
|
||||||
static const QString HLAYOUT;
|
|
||||||
static const QString GBOPTIONS;
|
|
||||||
static const QString RBALL;
|
|
||||||
static const QString RBFORWARD;
|
|
||||||
static const QString RBBACKWARD;
|
|
||||||
};
|
|
|
@ -1,24 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHexView/model/buffer/qhexbuffer.h>
|
|
||||||
|
|
||||||
class QDeviceBuffer: public QHexBuffer {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QDeviceBuffer(QObject* parent = nullptr);
|
|
||||||
virtual ~QDeviceBuffer();
|
|
||||||
uchar at(qint64 idx) override;
|
|
||||||
qint64 length() const override;
|
|
||||||
void insert(qint64 offset, const QByteArray& data) override;
|
|
||||||
void replace(qint64 offset, const QByteArray& data) override;
|
|
||||||
void remove(qint64 offset, int length) override;
|
|
||||||
QByteArray read(qint64 offset, int length) override;
|
|
||||||
bool read(QIODevice* device) override;
|
|
||||||
void write(QIODevice* device) override;
|
|
||||||
qint64 indexOf(const QByteArray& ba, qint64 from) override;
|
|
||||||
qint64 lastIndexOf(const QByteArray& ba, qint64 from) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QIODevice* m_device{nullptr};
|
|
||||||
};
|
|
|
@ -1,29 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QIODevice>
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
class QHexBuffer: public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QHexBuffer(QObject* parent = nullptr);
|
|
||||||
bool isEmpty() const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual uchar at(qint64 idx);
|
|
||||||
virtual bool accept(qint64 idx) const;
|
|
||||||
virtual void replace(qint64 offset, const QByteArray& data);
|
|
||||||
virtual void read(char* data, int size);
|
|
||||||
virtual void read(const QByteArray& ba);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual qint64 length() const = 0;
|
|
||||||
virtual void insert(qint64 offset, const QByteArray& data) = 0;
|
|
||||||
virtual void remove(qint64 offset, int length) = 0;
|
|
||||||
virtual QByteArray read(qint64 offset, int length) = 0;
|
|
||||||
virtual bool read(QIODevice* iodevice) = 0;
|
|
||||||
virtual void write(QIODevice* iodevice) = 0;
|
|
||||||
virtual qint64 indexOf(const QByteArray& ba, qint64 from) = 0;
|
|
||||||
virtual qint64 lastIndexOf(const QByteArray& ba, qint64 from) = 0;
|
|
||||||
};
|
|
|
@ -1,20 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHexView/model/buffer/qdevicebuffer.h>
|
|
||||||
|
|
||||||
class QMappedFileBuffer: public QDeviceBuffer {
|
|
||||||
public:
|
|
||||||
explicit QMappedFileBuffer(QObject* parent = nullptr);
|
|
||||||
virtual ~QMappedFileBuffer();
|
|
||||||
|
|
||||||
public:
|
|
||||||
QByteArray read(qint64 offset, int length) override;
|
|
||||||
bool read(QIODevice* iodevice) override;
|
|
||||||
void write(QIODevice* iodevice) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void remap();
|
|
||||||
|
|
||||||
private:
|
|
||||||
uchar* m_mappeddata{nullptr};
|
|
||||||
};
|
|
|
@ -1,22 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHexView/model/buffer/qhexbuffer.h>
|
|
||||||
|
|
||||||
class QMemoryBuffer: public QHexBuffer {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QMemoryBuffer(QObject* parent = nullptr);
|
|
||||||
uchar at(qint64 idx) override;
|
|
||||||
qint64 length() const override;
|
|
||||||
void insert(qint64 offset, const QByteArray& data) override;
|
|
||||||
void remove(qint64 offset, int length) override;
|
|
||||||
QByteArray read(qint64 offset, int length) override;
|
|
||||||
bool read(QIODevice* device) override;
|
|
||||||
void write(QIODevice* device) override;
|
|
||||||
qint64 indexOf(const QByteArray& ba, qint64 from) override;
|
|
||||||
qint64 lastIndexOf(const QByteArray& ba, qint64 from) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QByteArray m_buffer;
|
|
||||||
};
|
|
|
@ -1,12 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHexView/model/buffer/qdevicebuffer.h>
|
|
||||||
|
|
||||||
class QMemoryRefBuffer: public QDeviceBuffer {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QMemoryRefBuffer(QObject* parent = nullptr);
|
|
||||||
bool read(QIODevice* device) override;
|
|
||||||
void write(QIODevice* device) override;
|
|
||||||
};
|
|
|
@ -1,19 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHexView/model/buffer/qhexbuffer.h>
|
|
||||||
#include <QUndoCommand>
|
|
||||||
|
|
||||||
class QHexDocument;
|
|
||||||
|
|
||||||
class HexCommand: public QUndoCommand {
|
|
||||||
public:
|
|
||||||
HexCommand(QHexBuffer* buffer, QHexDocument* document,
|
|
||||||
QUndoCommand* parent = nullptr);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QHexDocument* m_hexdocument;
|
|
||||||
QHexBuffer* m_buffer;
|
|
||||||
qint64 m_offset;
|
|
||||||
int m_length;
|
|
||||||
QByteArray m_data;
|
|
||||||
};
|
|
|
@ -1,11 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHexView/model/commands/hexcommand.h>
|
|
||||||
|
|
||||||
class InsertCommand: public HexCommand {
|
|
||||||
public:
|
|
||||||
InsertCommand(QHexBuffer* buffer, QHexDocument* document, qint64 offset,
|
|
||||||
const QByteArray& data, QUndoCommand* parent = nullptr);
|
|
||||||
void undo() override;
|
|
||||||
void redo() override;
|
|
||||||
};
|
|
|
@ -1,11 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHexView/model/commands/hexcommand.h>
|
|
||||||
|
|
||||||
class RemoveCommand: public HexCommand {
|
|
||||||
public:
|
|
||||||
RemoveCommand(QHexBuffer* buffer, QHexDocument* document, qint64 offset,
|
|
||||||
int length, QUndoCommand* parent = nullptr);
|
|
||||||
void undo() override;
|
|
||||||
void redo() override;
|
|
||||||
};
|
|
|
@ -1,14 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHexView/model/commands/hexcommand.h>
|
|
||||||
|
|
||||||
class ReplaceCommand: public HexCommand {
|
|
||||||
public:
|
|
||||||
ReplaceCommand(QHexBuffer* buffer, QHexDocument* document, qint64 offset,
|
|
||||||
const QByteArray& data, QUndoCommand* parent = nullptr);
|
|
||||||
void undo() override;
|
|
||||||
void redo() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QByteArray m_olddata;
|
|
||||||
};
|
|
|
@ -1,73 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHexView/model/qhexoptions.h>
|
|
||||||
#include <QHexView/model/qhexutils.h>
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
class QHexView;
|
|
||||||
|
|
||||||
class QHexCursor: public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum class Mode { Overwrite, Insert };
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit QHexCursor(const QHexOptions* options, QHexView* parent = nullptr);
|
|
||||||
|
|
||||||
public:
|
|
||||||
QHexView* hexView() const;
|
|
||||||
Mode mode() const;
|
|
||||||
qint64 line() const;
|
|
||||||
qint64 column() const;
|
|
||||||
qint64 offset() const;
|
|
||||||
qint64 address() const;
|
|
||||||
quint64 lineAddress() const;
|
|
||||||
qint64 selectionStartOffset() const;
|
|
||||||
qint64 selectionEndOffset() const;
|
|
||||||
qint64 selectionLength() const;
|
|
||||||
QHexPosition position() const;
|
|
||||||
QHexPosition selectionStart() const;
|
|
||||||
QHexPosition selectionEnd() const;
|
|
||||||
QByteArray selectedBytes() const;
|
|
||||||
bool hasSelection() const;
|
|
||||||
bool isSelected(qint64 line, qint64 column) const;
|
|
||||||
void setMode(Mode m);
|
|
||||||
void move(qint64 offset);
|
|
||||||
void move(qint64 line, qint64 column);
|
|
||||||
void move(QHexPosition pos);
|
|
||||||
void select(qint64 offset);
|
|
||||||
void select(qint64 line, qint64 column);
|
|
||||||
void select(QHexPosition pos);
|
|
||||||
void selectSize(qint64 length);
|
|
||||||
qint64 replace(const QVariant& oldvalue, const QVariant& newvalue,
|
|
||||||
qint64 offset, QHexFindMode mode = QHexFindMode::Text,
|
|
||||||
unsigned int options = QHexFindOptions::None,
|
|
||||||
QHexFindDirection fd = QHexFindDirection::Forward) const;
|
|
||||||
qint64 find(const QVariant& value, qint64 offset,
|
|
||||||
QHexFindMode mode = QHexFindMode::Text,
|
|
||||||
unsigned int options = QHexFindOptions::None,
|
|
||||||
QHexFindDirection fd = QHexFindDirection::Forward) const;
|
|
||||||
qint64 positionToOffset(QHexPosition pos) const;
|
|
||||||
QHexPosition offsetToPosition(qint64 offset) const;
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
void cut(bool hex = false);
|
|
||||||
void copy(bool hex = false) const;
|
|
||||||
void paste(bool hex = false);
|
|
||||||
void selectAll();
|
|
||||||
void removeSelection();
|
|
||||||
void clearSelection();
|
|
||||||
void switchMode();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void positionChanged();
|
|
||||||
void modeChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
const QHexOptions* m_options;
|
|
||||||
Mode m_mode{Mode::Overwrite};
|
|
||||||
QHexPosition m_position{}, m_selection{};
|
|
||||||
|
|
||||||
friend class QHexView;
|
|
||||||
};
|
|
|
@ -1,30 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHexView/model/qhexutils.h>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QTextCharFormat>
|
|
||||||
|
|
||||||
class QHexView;
|
|
||||||
|
|
||||||
class QHexDelegate: public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QHexDelegate(QObject* parent = nullptr);
|
|
||||||
virtual ~QHexDelegate() = default;
|
|
||||||
virtual QString addressHeader(const QHexView* hexview) const;
|
|
||||||
virtual QString hexHeader(const QHexView* hexview) const;
|
|
||||||
virtual QString asciiHeader(const QHexView* hexview) const;
|
|
||||||
virtual void renderAddress(quint64 address, QTextCharFormat& cf,
|
|
||||||
const QHexView* hexview) const;
|
|
||||||
virtual void renderHeader(QTextBlockFormat& bf,
|
|
||||||
const QHexView* hexview) const;
|
|
||||||
virtual void renderHeaderPart(const QString& s, QHexArea area,
|
|
||||||
QTextCharFormat& cf,
|
|
||||||
const QHexView* hexview) const;
|
|
||||||
virtual bool render(quint64 offset, quint8 b, QTextCharFormat& outcf,
|
|
||||||
const QHexView* hexview) const;
|
|
||||||
virtual bool paintSeparator(QPainter* painter, QLineF line,
|
|
||||||
const QHexView* hexview) const;
|
|
||||||
virtual void paint(QPainter* painter, const QHexView* hexview) const;
|
|
||||||
};
|
|
|
@ -1,102 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QHexView/model/buffer/qhexbuffer.h>
|
|
||||||
#include <QHexView/model/qhexmetadata.h>
|
|
||||||
#include <QUndoStack>
|
|
||||||
|
|
||||||
class QHexCursor;
|
|
||||||
|
|
||||||
class QHexDocument: public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum class ChangeReason { Insert, Remove, Replace };
|
|
||||||
enum class FindDirection { Forward, Backward };
|
|
||||||
Q_ENUM(ChangeReason);
|
|
||||||
Q_ENUM(FindDirection);
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit QHexDocument(QHexBuffer* buffer, QObject* parent = nullptr);
|
|
||||||
bool accept(qint64 idx) const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool isEmpty() const;
|
|
||||||
bool isModified() const;
|
|
||||||
bool canUndo() const;
|
|
||||||
bool canRedo() const;
|
|
||||||
void setData(const QByteArray& ba);
|
|
||||||
void setData(QHexBuffer* buffer);
|
|
||||||
qint64 length() const;
|
|
||||||
qint64 indexOf(const QByteArray& ba, qint64 from = 0);
|
|
||||||
qint64 lastIndexOf(const QByteArray& ba, qint64 from = 0);
|
|
||||||
QByteArray read(qint64 offset, int len = 0) const;
|
|
||||||
uchar at(int offset) const;
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
void clearModified();
|
|
||||||
void undo();
|
|
||||||
void redo();
|
|
||||||
void insert(qint64 offset, uchar b);
|
|
||||||
void replace(qint64 offset, uchar b);
|
|
||||||
void insert(qint64 offset, const QByteArray& data);
|
|
||||||
void replace(qint64 offset, const QByteArray& data);
|
|
||||||
void remove(qint64 offset, int len);
|
|
||||||
bool saveTo(QIODevice* device);
|
|
||||||
|
|
||||||
public:
|
|
||||||
template<typename T, bool Owned = true>
|
|
||||||
static QHexDocument* fromDevice(QIODevice* iodevice,
|
|
||||||
QObject* parent = nullptr);
|
|
||||||
template<typename T>
|
|
||||||
static QHexDocument* fromMemory(char* data, int size,
|
|
||||||
QObject* parent = nullptr);
|
|
||||||
template<typename T>
|
|
||||||
static QHexDocument* fromMemory(const QByteArray& ba,
|
|
||||||
QObject* parent = nullptr);
|
|
||||||
static QHexDocument* fromBuffer(QHexBuffer* buffer,
|
|
||||||
QObject* parent = nullptr);
|
|
||||||
static QHexDocument* fromLargeFile(QString filename,
|
|
||||||
QObject* parent = nullptr);
|
|
||||||
static QHexDocument* fromMappedFile(QString filename,
|
|
||||||
QObject* parent = nullptr);
|
|
||||||
static QHexDocument* fromFile(QString filename, QObject* parent = nullptr);
|
|
||||||
static QHexDocument* create(QObject* parent = nullptr);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void modifiedChanged(bool modified);
|
|
||||||
void canUndoChanged(bool canundo);
|
|
||||||
void canRedoChanged(bool canredo);
|
|
||||||
void dataChanged(const QByteArray& data, quint64 offset,
|
|
||||||
QHexDocument::ChangeReason reason);
|
|
||||||
void changed();
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QHexBuffer* m_buffer;
|
|
||||||
QUndoStack m_undostack;
|
|
||||||
|
|
||||||
friend class QHexView;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, bool Owned>
|
|
||||||
QHexDocument* QHexDocument::fromDevice(QIODevice* iodevice, QObject* parent) {
|
|
||||||
QHexBuffer* hexbuffer = new T(parent);
|
|
||||||
if(Owned)
|
|
||||||
iodevice->setParent(hexbuffer);
|
|
||||||
return hexbuffer->read(iodevice) ? new QHexDocument(hexbuffer, parent)
|
|
||||||
: nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
QHexDocument* QHexDocument::fromMemory(char* data, int size, QObject* parent) {
|
|
||||||
QHexBuffer* hexbuffer = new T();
|
|
||||||
hexbuffer->read(data, size);
|
|
||||||
return new QHexDocument(hexbuffer, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
QHexDocument* QHexDocument::fromMemory(const QByteArray& ba, QObject* parent) {
|
|
||||||
QHexBuffer* hexbuffer = new T();
|
|
||||||
hexbuffer->read(ba);
|
|
||||||
return new QHexDocument(hexbuffer, parent);
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QColor>
|
|
||||||
#include <QHash>
|
|
||||||
#include <QHexView/model/qhexoptions.h>
|
|
||||||
#include <QList>
|
|
||||||
#include <QObject>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
struct QHexMetadataItem {
|
|
||||||
qint64 begin, end;
|
|
||||||
QColor foreground, background;
|
|
||||||
QString comment;
|
|
||||||
};
|
|
||||||
|
|
||||||
using QHexMetadataLine = QList<QHexMetadataItem>;
|
|
||||||
|
|
||||||
class QHexMetadata: public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private:
|
|
||||||
using ClearMetadataCallback = std::function<bool(QHexMetadataItem&)>;
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit QHexMetadata(const QHexOptions* options,
|
|
||||||
QObject* parent = nullptr);
|
|
||||||
|
|
||||||
public:
|
|
||||||
const QHexMetadataLine* find(qint64 line) const;
|
|
||||||
QString getComment(qint64 line, qint64 column) const;
|
|
||||||
void removeMetadata(qint64 line);
|
|
||||||
void removeBackground(qint64 line);
|
|
||||||
void removeForeground(qint64 line);
|
|
||||||
void removeComments(qint64 line);
|
|
||||||
void unhighlight(qint64 line);
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
public:
|
|
||||||
inline void setMetadata(qint64 begin, qint64 end, const QColor& fgcolor,
|
|
||||||
const QColor& bgcolor, const QString& comment) {
|
|
||||||
this->setMetadata({begin, end, fgcolor, bgcolor, comment});
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setForeground(qint64 begin, qint64 end, const QColor& fgcolor) {
|
|
||||||
this->setMetadata(begin, end, fgcolor, QColor(), QString());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setBackground(qint64 begin, qint64 end, const QColor& bgcolor) {
|
|
||||||
this->setMetadata(begin, end, QColor(), bgcolor, QString());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setComment(qint64 begin, qint64 end, const QString& comment) {
|
|
||||||
this->setMetadata(begin, end, QColor(), QColor(), comment);
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void setMetadataSize(qint64 begin, qint64 length,
|
|
||||||
const QColor& fgcolor, const QColor& bgcolor,
|
|
||||||
const QString& comment) {
|
|
||||||
this->setMetadata({begin, begin + length, fgcolor, bgcolor, comment});
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setForegroundSize(qint64 begin, qint64 length,
|
|
||||||
const QColor& fgcolor) {
|
|
||||||
this->setForeground(begin, begin + length, fgcolor);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setBackgroundSize(qint64 begin, qint64 length,
|
|
||||||
const QColor& bgcolor) {
|
|
||||||
this->setBackground(begin, begin + length, bgcolor);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setCommentSize(qint64 begin, qint64 length,
|
|
||||||
const QString& comment) {
|
|
||||||
this->setComment(begin, begin + length, comment);
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
void copy(const QHexMetadata* metadata);
|
|
||||||
void clearMetadata(qint64 line, ClearMetadataCallback&& cb);
|
|
||||||
void setMetadata(const QHexMetadataItem& mi);
|
|
||||||
void invalidate();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void changed();
|
|
||||||
void cleared();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QHash<qint64, QHexMetadataLine> m_metadata;
|
|
||||||
const QHexOptions* m_options;
|
|
||||||
|
|
||||||
friend class QHexView;
|
|
||||||
};
|
|
|
@ -1,66 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QByteArray>
|
|
||||||
#include <QPair>
|
|
||||||
#include <QString>
|
|
||||||
#include <QVariant>
|
|
||||||
|
|
||||||
struct QHexOptions;
|
|
||||||
class QHexView;
|
|
||||||
|
|
||||||
namespace QHexFindOptions {
|
|
||||||
|
|
||||||
enum : unsigned int {
|
|
||||||
None = (1 << 0),
|
|
||||||
CaseSensitive = (1 << 1),
|
|
||||||
Int8 = (1 << 2),
|
|
||||||
Int16 = (1 << 3),
|
|
||||||
Int32 = (1 << 4),
|
|
||||||
Int64 = (1 << 5),
|
|
||||||
Float = (1 << 6),
|
|
||||||
Double = (1 << 7),
|
|
||||||
|
|
||||||
BigEndian = (1 << 11),
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class QHexFindMode { Text, Hex, Int, Float };
|
|
||||||
enum class QHexFindDirection { All, Forward, Backward };
|
|
||||||
enum class QHexArea { Header, Address, Hex, Ascii, Extra };
|
|
||||||
|
|
||||||
struct QHexPosition {
|
|
||||||
qint64 line;
|
|
||||||
qint64 column;
|
|
||||||
static inline QHexPosition invalid() { return {-1, -1}; }
|
|
||||||
inline bool isValid() const { return line >= 0 && column >= 0; }
|
|
||||||
inline bool operator==(const QHexPosition& rhs) const {
|
|
||||||
return (line == rhs.line) && (column == rhs.column);
|
|
||||||
}
|
|
||||||
inline bool operator!=(const QHexPosition& rhs) const {
|
|
||||||
return (line != rhs.line) || (column != rhs.column);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace QHexUtils {
|
|
||||||
|
|
||||||
bool isHex(char ch);
|
|
||||||
QByteArray toHex(const QByteArray& ba, char sep);
|
|
||||||
QByteArray toHex(const QByteArray& ba);
|
|
||||||
qint64 positionToOffset(const QHexOptions* options, QHexPosition pos);
|
|
||||||
QHexPosition offsetToPosition(const QHexOptions* options, qint64 offset);
|
|
||||||
bool checkPattern(QString pattern);
|
|
||||||
|
|
||||||
QPair<qint64, qint64> find(const QHexView* hexview, QVariant value,
|
|
||||||
qint64 startoffset = 0,
|
|
||||||
QHexFindMode mode = QHexFindMode::Text,
|
|
||||||
unsigned int options = QHexFindOptions::None,
|
|
||||||
QHexFindDirection fd = QHexFindDirection::Forward);
|
|
||||||
|
|
||||||
QPair<qint64, qint64>
|
|
||||||
replace(const QHexView* hexview, QVariant oldvalue, QVariant newvalue,
|
|
||||||
qint64 startoffset = 0, QHexFindMode mode = QHexFindMode::Text,
|
|
||||||
unsigned int options = QHexFindOptions::None,
|
|
||||||
QHexFindDirection fd = QHexFindDirection::Forward);
|
|
||||||
|
|
||||||
} // namespace QHexUtils
|
|
|
@ -1,184 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define QHEXVIEW_VERSION 5.0
|
|
||||||
|
|
||||||
#include <QAbstractScrollArea>
|
|
||||||
#include <QFontMetricsF>
|
|
||||||
#include <QHexView/model/qhexcursor.h>
|
|
||||||
#include <QHexView/model/qhexdelegate.h>
|
|
||||||
#include <QHexView/model/qhexdocument.h>
|
|
||||||
#include <QList>
|
|
||||||
#include <QRectF>
|
|
||||||
#include <QTextCharFormat>
|
|
||||||
|
|
||||||
#if defined(QHEXVIEW_ENABLE_DIALOGS)
|
|
||||||
class HexFindDialog;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class QHexView: public QAbstractScrollArea {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum class CopyMode { Visual, HexArraySquare, HexArrayCurly, HexArrayChar };
|
|
||||||
Q_ENUM(CopyMode);
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QHexView(QWidget* parent = nullptr);
|
|
||||||
QRectF headerRect() const;
|
|
||||||
QRectF addressRect() const;
|
|
||||||
QRectF hexRect() const;
|
|
||||||
QRectF asciiRect() const;
|
|
||||||
QHexDocument* hexDocument() const;
|
|
||||||
QHexCursor* hexCursor() const;
|
|
||||||
const QHexMetadata* hexMetadata() const;
|
|
||||||
QHexOptions options() const;
|
|
||||||
QColor getReadableColor(QColor c) const;
|
|
||||||
QByteArray selectedBytes() const;
|
|
||||||
QByteArray getLine(qint64 line) const;
|
|
||||||
unsigned int addressWidth() const;
|
|
||||||
unsigned int lineLength() const;
|
|
||||||
bool isModified() const;
|
|
||||||
bool canUndo() const;
|
|
||||||
bool canRedo() const;
|
|
||||||
quint64 offset() const;
|
|
||||||
quint64 address() const;
|
|
||||||
QHexPosition positionFromOffset(quint64 offset) const;
|
|
||||||
QHexPosition positionFromAddress(quint64 address) const;
|
|
||||||
QHexPosition position() const;
|
|
||||||
QHexPosition selectionStart() const;
|
|
||||||
QHexPosition selectionEnd() const;
|
|
||||||
quint64 selectionStartOffset() const;
|
|
||||||
quint64 selectionEndOffset() const;
|
|
||||||
quint64 baseAddress() const;
|
|
||||||
quint64 lines() const;
|
|
||||||
qint64 replace(const QVariant& oldvalue, const QVariant& newvalue,
|
|
||||||
qint64 offset, QHexFindMode mode = QHexFindMode::Text,
|
|
||||||
unsigned int options = QHexFindOptions::None,
|
|
||||||
QHexFindDirection fd = QHexFindDirection::Forward) const;
|
|
||||||
qint64 find(const QVariant& value, qint64 offset,
|
|
||||||
QHexFindMode mode = QHexFindMode::Text,
|
|
||||||
unsigned int options = QHexFindOptions::None,
|
|
||||||
QHexFindDirection fd = QHexFindDirection::Forward) const;
|
|
||||||
void setOptions(const QHexOptions& options);
|
|
||||||
void setBaseAddress(quint64 baseaddress);
|
|
||||||
void setDelegate(QHexDelegate* rd);
|
|
||||||
void setDocument(QHexDocument* doc);
|
|
||||||
void setData(const QByteArray& ba);
|
|
||||||
void setData(QHexBuffer* buffer);
|
|
||||||
void setCursorMode(QHexCursor::Mode mode);
|
|
||||||
void setByteColor(quint8 b, QHexColor c);
|
|
||||||
void setByteForeground(quint8 b, QColor c);
|
|
||||||
void setByteBackground(quint8 b, QColor c);
|
|
||||||
void setMetadata(qint64 begin, qint64 end, const QColor& fgcolor,
|
|
||||||
const QColor& bgcolor, const QString& comment);
|
|
||||||
void setForeground(qint64 begin, qint64 end, const QColor& fgcolor);
|
|
||||||
void setBackground(qint64 begin, qint64 end, const QColor& bgcolor);
|
|
||||||
void setComment(qint64 begin, qint64 end, const QString& comment);
|
|
||||||
void setMetadataSize(qint64 begin, qint64 length, const QColor& fgcolor,
|
|
||||||
const QColor& bgcolor, const QString& comment);
|
|
||||||
void setForegroundSize(qint64 begin, qint64 length, const QColor& fgcolor);
|
|
||||||
void setBackgroundSize(qint64 begin, qint64 length, const QColor& bgcolor);
|
|
||||||
void setCommentSize(qint64 begin, qint64 length, const QString& comment);
|
|
||||||
void removeMetadata(qint64 line);
|
|
||||||
void removeBackground(qint64 line);
|
|
||||||
void removeForeground(qint64 line);
|
|
||||||
void removeComments(qint64 line);
|
|
||||||
void unhighlight(qint64 line);
|
|
||||||
void clearMetadata();
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
#if defined(QHEXVIEW_ENABLE_DIALOGS)
|
|
||||||
void showFind();
|
|
||||||
void showReplace();
|
|
||||||
#endif
|
|
||||||
void undo();
|
|
||||||
void redo();
|
|
||||||
void cut(bool hex = false);
|
|
||||||
void copyAs(CopyMode mode = CopyMode::Visual) const;
|
|
||||||
void copy(bool hex = false) const;
|
|
||||||
void paste(bool hex = false);
|
|
||||||
void clearModified();
|
|
||||||
void selectAll();
|
|
||||||
void removeSelection();
|
|
||||||
void switchMode();
|
|
||||||
void setAddressWidth(unsigned int w);
|
|
||||||
void setLineLength(unsigned int l);
|
|
||||||
void setGroupLength(unsigned int l);
|
|
||||||
void setScrollSteps(int scrollsteps);
|
|
||||||
void setReadOnly(bool r);
|
|
||||||
void setAutoWidth(bool r);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void paint(QPainter* painter) const;
|
|
||||||
void checkOptions();
|
|
||||||
void checkState();
|
|
||||||
void checkAndUpdate(bool calccolumns = false);
|
|
||||||
void calcColumns();
|
|
||||||
void ensureVisible();
|
|
||||||
void drawSeparators(QPainter* p) const;
|
|
||||||
void drawHeader(QTextCursor& c) const;
|
|
||||||
void drawDocument(QTextCursor& c) const;
|
|
||||||
QTextCharFormat drawFormat(QTextCursor& c, quint8 b, const QString& s,
|
|
||||||
QHexArea area, qint64 line, qint64 column,
|
|
||||||
bool applyformat) const;
|
|
||||||
unsigned int calcAddressWidth() const;
|
|
||||||
int visibleLines(bool absolute = false) const;
|
|
||||||
qint64 getLastColumn(qint64 line) const;
|
|
||||||
qint64 lastLine() const;
|
|
||||||
qreal getNCellsWidth(int n) const;
|
|
||||||
qreal hexColumnWidth() const;
|
|
||||||
qreal hexColumnX() const;
|
|
||||||
qreal asciiColumnX() const;
|
|
||||||
qreal endColumnX() const;
|
|
||||||
qreal cellWidth() const;
|
|
||||||
qreal lineHeight() const;
|
|
||||||
qint64 positionFromLineCol(qint64 line, qint64 col) const;
|
|
||||||
QHexPosition positionFromPoint(QPoint pt) const;
|
|
||||||
QPoint absolutePoint(QPoint pt) const;
|
|
||||||
QHexArea areaFromPoint(QPoint pt) const;
|
|
||||||
void moveNext(bool select = false);
|
|
||||||
void movePrevious(bool select = false);
|
|
||||||
bool keyPressMove(QKeyEvent* e);
|
|
||||||
bool keyPressTextInput(QKeyEvent* e);
|
|
||||||
bool keyPressAction(QKeyEvent* e);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool event(QEvent* e) override;
|
|
||||||
void showEvent(QShowEvent* e) override;
|
|
||||||
void paintEvent(QPaintEvent*) override;
|
|
||||||
void resizeEvent(QResizeEvent* e) override;
|
|
||||||
void focusInEvent(QFocusEvent* e) override;
|
|
||||||
void focusOutEvent(QFocusEvent* e) override;
|
|
||||||
void mousePressEvent(QMouseEvent* e) override;
|
|
||||||
void mouseMoveEvent(QMouseEvent* e) override;
|
|
||||||
void wheelEvent(QWheelEvent* e) override;
|
|
||||||
void keyPressEvent(QKeyEvent* e) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static QString reduced(const QString& s, int maxlen);
|
|
||||||
static bool isColorLight(QColor c);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void dataChanged(const QByteArray& data, quint64 offset,
|
|
||||||
QHexDocument::ChangeReason reason);
|
|
||||||
void modifiedChanged(bool modified);
|
|
||||||
void positionChanged();
|
|
||||||
void modeChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_readonly{false}, m_writing{false}, m_autowidth{false};
|
|
||||||
QHexArea m_currentarea{QHexArea::Ascii};
|
|
||||||
QList<QRectF> m_hexcolumns;
|
|
||||||
QFontMetricsF m_fontmetrics;
|
|
||||||
QHexOptions m_options;
|
|
||||||
QHexCursor* m_hexcursor{nullptr};
|
|
||||||
QHexDocument* m_hexdocument{nullptr};
|
|
||||||
QHexMetadata* m_hexmetadata{nullptr};
|
|
||||||
QHexDelegate* m_hexdelegate{nullptr};
|
|
||||||
#if defined(QHEXVIEW_ENABLE_DIALOGS)
|
|
||||||
HexFindDialog *m_hexdlgfind{nullptr}, *m_hexdlgreplace{nullptr};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
friend class QHexDelegate;
|
|
||||||
friend class QHexCursor;
|
|
||||||
};
|
|
|
@ -1,418 +0,0 @@
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QComboBox>
|
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QGroupBox>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QHexView/dialogs/hexfinddialog.h>
|
|
||||||
#include <QHexView/qhexview.h>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QLineEdit>
|
|
||||||
#include <QList>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QPair>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QRadioButton>
|
|
||||||
#include <QRegularExpression>
|
|
||||||
#include <QRegularExpressionValidator>
|
|
||||||
#include <QSpacerItem>
|
|
||||||
#include <QStackedLayout>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
const QString HexFindDialog::BUTTONBOX = "qhexview_buttonbox";
|
|
||||||
const QString HexFindDialog::CBFINDMODE = "qhexview_cbfindmode";
|
|
||||||
const QString HexFindDialog::LEFIND = "qhexview_lefind";
|
|
||||||
const QString HexFindDialog::LEREPLACE = "qhexview_lereplace";
|
|
||||||
const QString HexFindDialog::HLAYOUT = "qhexview_hlayout";
|
|
||||||
const QString HexFindDialog::GBOPTIONS = "qhexview_gboptions";
|
|
||||||
const QString HexFindDialog::RBALL = "qhexview_rball";
|
|
||||||
const QString HexFindDialog::RBFORWARD = "qhexview_rbforward";
|
|
||||||
const QString HexFindDialog::RBBACKWARD = "qhexview_rbbackward";
|
|
||||||
|
|
||||||
HexFindDialog::HexFindDialog(Type type, QHexView* parent)
|
|
||||||
: QDialog{parent}, m_type{type} {
|
|
||||||
m_hexvalidator = new QRegularExpressionValidator(
|
|
||||||
QRegularExpression{"[0-9A-Fa-f ]+"}, this);
|
|
||||||
m_hexpvalidator = new QRegularExpressionValidator(
|
|
||||||
QRegularExpression{"[0-9A-Fa-f \\?]+"}, this);
|
|
||||||
m_dblvalidator = new QDoubleValidator(this);
|
|
||||||
m_intvalidator = new QIntValidator(this);
|
|
||||||
|
|
||||||
this->setWindowTitle(type == Type::Replace ? tr("Replace...")
|
|
||||||
: tr("Find..."));
|
|
||||||
|
|
||||||
auto* vlayout = new QVBoxLayout(this);
|
|
||||||
auto* gridlayout = new QGridLayout();
|
|
||||||
|
|
||||||
auto* cbfindmode = new QComboBox(this);
|
|
||||||
cbfindmode->setObjectName(HexFindDialog::CBFINDMODE);
|
|
||||||
cbfindmode->addItem("Text", static_cast<int>(QHexFindMode::Text));
|
|
||||||
cbfindmode->addItem("Hex", static_cast<int>(QHexFindMode::Hex));
|
|
||||||
cbfindmode->addItem("Int", static_cast<int>(QHexFindMode::Int));
|
|
||||||
cbfindmode->addItem("Float", static_cast<int>(QHexFindMode::Float));
|
|
||||||
|
|
||||||
QLineEdit *lereplace = nullptr, *lefind = new QLineEdit(this);
|
|
||||||
lefind->setObjectName(HexFindDialog::LEFIND);
|
|
||||||
|
|
||||||
gridlayout->addWidget(new QLabel(tr("Mode:"), this), 0, 0, Qt::AlignRight);
|
|
||||||
gridlayout->addWidget(cbfindmode, 0, 1);
|
|
||||||
gridlayout->addWidget(new QLabel(tr("Find:"), this), 1, 0, Qt::AlignRight);
|
|
||||||
gridlayout->addWidget(lefind, 1, 1);
|
|
||||||
|
|
||||||
if(type == Type::Replace) {
|
|
||||||
lereplace = new QLineEdit(this);
|
|
||||||
lereplace->setObjectName(HexFindDialog::LEREPLACE);
|
|
||||||
|
|
||||||
gridlayout->addWidget(new QLabel(tr("Replace:"), this), 2, 0,
|
|
||||||
Qt::AlignRight);
|
|
||||||
gridlayout->addWidget(lereplace, 2, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
vlayout->addLayout(gridlayout);
|
|
||||||
|
|
||||||
auto* gboptions = new QGroupBox(this);
|
|
||||||
gboptions->setObjectName(HexFindDialog::GBOPTIONS);
|
|
||||||
gboptions->setTitle(tr("Options"));
|
|
||||||
gboptions->setLayout(new QStackedLayout());
|
|
||||||
|
|
||||||
QGroupBox* gbdirection = new QGroupBox(this);
|
|
||||||
gbdirection->setTitle(tr("Find direction"));
|
|
||||||
auto* gbvlayout = new QVBoxLayout(gbdirection);
|
|
||||||
|
|
||||||
auto* rball = new QRadioButton("All", gbdirection);
|
|
||||||
rball->setObjectName(HexFindDialog::RBALL);
|
|
||||||
auto* rbforward = new QRadioButton("Forward", gbdirection);
|
|
||||||
rbforward->setObjectName(HexFindDialog::RBFORWARD);
|
|
||||||
rbforward->setChecked(true);
|
|
||||||
auto* rbbackward = new QRadioButton("Backward", gbdirection);
|
|
||||||
rbbackward->setObjectName(HexFindDialog::RBBACKWARD);
|
|
||||||
|
|
||||||
gbvlayout->addWidget(rball);
|
|
||||||
gbvlayout->addWidget(rbforward);
|
|
||||||
gbvlayout->addWidget(rbbackward);
|
|
||||||
gbvlayout->addSpacerItem(
|
|
||||||
new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
|
||||||
|
|
||||||
auto* hlayout = new QHBoxLayout();
|
|
||||||
hlayout->setObjectName(HexFindDialog::HLAYOUT);
|
|
||||||
hlayout->addWidget(gboptions, 1);
|
|
||||||
hlayout->addWidget(gbdirection);
|
|
||||||
vlayout->addLayout(hlayout, 1);
|
|
||||||
|
|
||||||
auto* buttonbox = new QDialogButtonBox(this);
|
|
||||||
buttonbox->setOrientation(Qt::Horizontal);
|
|
||||||
|
|
||||||
if(type == Type::Replace)
|
|
||||||
buttonbox->setStandardButtons(QDialogButtonBox::Ok |
|
|
||||||
QDialogButtonBox::Apply |
|
|
||||||
QDialogButtonBox::Cancel);
|
|
||||||
else
|
|
||||||
buttonbox->setStandardButtons(QDialogButtonBox::Ok |
|
|
||||||
QDialogButtonBox::Cancel);
|
|
||||||
|
|
||||||
buttonbox->setObjectName(HexFindDialog::BUTTONBOX);
|
|
||||||
buttonbox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
|
||||||
buttonbox->button(QDialogButtonBox::Ok)->setText(tr("Find"));
|
|
||||||
|
|
||||||
if(type == Type::Replace) {
|
|
||||||
buttonbox->button(QDialogButtonBox::Apply)->setEnabled(false);
|
|
||||||
buttonbox->button(QDialogButtonBox::Apply)->setText(tr("Replace"));
|
|
||||||
}
|
|
||||||
|
|
||||||
vlayout->addWidget(buttonbox);
|
|
||||||
|
|
||||||
connect(lefind, &QLineEdit::textChanged, this,
|
|
||||||
&HexFindDialog::validateActions);
|
|
||||||
connect(cbfindmode, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
|
||||||
this, &HexFindDialog::updateFindOptions);
|
|
||||||
connect(buttonbox, &QDialogButtonBox::accepted, this, &HexFindDialog::find);
|
|
||||||
connect(buttonbox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
|
||||||
connect(parent, &QHexView::positionChanged, this,
|
|
||||||
[this]() { m_startoffset = -1; });
|
|
||||||
|
|
||||||
if(lereplace) {
|
|
||||||
connect(buttonbox->button(QDialogButtonBox::Apply),
|
|
||||||
&QPushButton::clicked, this, &HexFindDialog::replace);
|
|
||||||
connect(lereplace, &QLineEdit::textChanged, this,
|
|
||||||
&HexFindDialog::validateActions);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->prepareTextMode(gboptions->layout());
|
|
||||||
this->prepareHexMode(gboptions->layout());
|
|
||||||
this->prepareIntMode(gboptions->layout());
|
|
||||||
this->prepareFloatMode(gboptions->layout());
|
|
||||||
this->updateFindOptions(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
QHexView* HexFindDialog::hexView() const {
|
|
||||||
return qobject_cast<QHexView*>(this->parentWidget());
|
|
||||||
}
|
|
||||||
|
|
||||||
void HexFindDialog::updateFindOptions(int) {
|
|
||||||
QGroupBox* gboptions =
|
|
||||||
this->findChild<QGroupBox*>(HexFindDialog::GBOPTIONS);
|
|
||||||
|
|
||||||
QLineEdit* lefind = this->findChild<QLineEdit*>(HexFindDialog::LEFIND);
|
|
||||||
QLineEdit* lereplace =
|
|
||||||
this->findChild<QLineEdit*>(HexFindDialog::LEREPLACE);
|
|
||||||
lefind->clear();
|
|
||||||
if(lereplace)
|
|
||||||
lereplace->clear();
|
|
||||||
|
|
||||||
bool ok = false;
|
|
||||||
QHexFindMode mode = static_cast<QHexFindMode>(
|
|
||||||
this->findChild<QComboBox*>(HexFindDialog::CBFINDMODE)
|
|
||||||
->currentData()
|
|
||||||
.toInt(&ok));
|
|
||||||
if(!ok)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_findoptions = QHexFindOptions::None;
|
|
||||||
m_oldidxbits = m_oldidxendian = -1;
|
|
||||||
|
|
||||||
auto* stack = qobject_cast<QStackedLayout*>(gboptions->layout());
|
|
||||||
|
|
||||||
switch(mode) {
|
|
||||||
case QHexFindMode::Text: {
|
|
||||||
lefind->setValidator(nullptr);
|
|
||||||
if(lereplace)
|
|
||||||
lereplace->setValidator(nullptr);
|
|
||||||
|
|
||||||
stack->setCurrentIndex(0);
|
|
||||||
gboptions->setVisible(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case QHexFindMode::Hex: {
|
|
||||||
lefind->setValidator(m_hexpvalidator);
|
|
||||||
if(lereplace)
|
|
||||||
lereplace->setValidator(m_hexvalidator);
|
|
||||||
stack->setCurrentIndex(1);
|
|
||||||
gboptions->setVisible(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case QHexFindMode::Int: {
|
|
||||||
lefind->setValidator(m_intvalidator);
|
|
||||||
if(lereplace)
|
|
||||||
lereplace->setValidator(m_intvalidator);
|
|
||||||
|
|
||||||
stack->setCurrentIndex(2);
|
|
||||||
gboptions->setVisible(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case QHexFindMode::Float: {
|
|
||||||
lefind->setValidator(m_dblvalidator);
|
|
||||||
if(lereplace)
|
|
||||||
lereplace->setValidator(m_dblvalidator);
|
|
||||||
|
|
||||||
stack->setCurrentIndex(3);
|
|
||||||
gboptions->setVisible(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HexFindDialog::validateIntRange(uint v) const {
|
|
||||||
if(m_findoptions & QHexFindOptions::Int8)
|
|
||||||
return !(v > std::numeric_limits<quint8>::max());
|
|
||||||
if(m_findoptions & QHexFindOptions::Int16)
|
|
||||||
return !(v > std::numeric_limits<quint16>::max());
|
|
||||||
if(m_findoptions & QHexFindOptions::Int32)
|
|
||||||
return !(v > std::numeric_limits<quint32>::max());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HexFindDialog::checkResult(const QString& q, qint64 offset,
|
|
||||||
QHexFindDirection fd) {
|
|
||||||
if(offset == -1) {
|
|
||||||
QMessageBox::information(this, tr("Not found"),
|
|
||||||
tr("Cannot find '%1'").arg(q));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fd == QHexFindDirection::Backward)
|
|
||||||
m_startoffset = this->hexView()->selectionStartOffset() - 1;
|
|
||||||
else
|
|
||||||
m_startoffset = this->hexView()->selectionEndOffset() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HexFindDialog::validateActions() {
|
|
||||||
auto mode = static_cast<QHexFindMode>(
|
|
||||||
this->findChild<QComboBox*>(HexFindDialog::CBFINDMODE)
|
|
||||||
->currentData()
|
|
||||||
.toUInt());
|
|
||||||
auto* lefind = this->findChild<QLineEdit*>(HexFindDialog::LEFIND);
|
|
||||||
auto* lereplace = this->findChild<QLineEdit*>(HexFindDialog::LEREPLACE);
|
|
||||||
auto* buttonbox =
|
|
||||||
this->findChild<QDialogButtonBox*>(HexFindDialog::BUTTONBOX);
|
|
||||||
|
|
||||||
bool findenable = false, replaceenable = false;
|
|
||||||
|
|
||||||
switch(mode) {
|
|
||||||
case QHexFindMode::Hex:
|
|
||||||
findenable = QHexUtils::checkPattern(lefind->text());
|
|
||||||
replaceenable = findenable;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QHexFindMode::Float: {
|
|
||||||
lefind->text().toFloat(&findenable);
|
|
||||||
if(lereplace && findenable)
|
|
||||||
lereplace->text().toFloat(&replaceenable);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case QHexFindMode::Int: {
|
|
||||||
auto v = lefind->text().toUInt(&findenable);
|
|
||||||
if(findenable && !this->validateIntRange(v))
|
|
||||||
findenable = false;
|
|
||||||
if(lereplace && findenable)
|
|
||||||
lereplace->text().toUInt(&replaceenable);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
findenable = !lefind->text().isEmpty();
|
|
||||||
replaceenable = findenable;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(lereplace)
|
|
||||||
buttonbox->button(QDialogButtonBox::Apply)->setEnabled(replaceenable);
|
|
||||||
buttonbox->button(QDialogButtonBox::Ok)->setEnabled(findenable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HexFindDialog::replace() {
|
|
||||||
QString q1;
|
|
||||||
QHexFindMode mode;
|
|
||||||
QHexFindDirection fd;
|
|
||||||
|
|
||||||
if(!this->prepareOptions(q1, mode, fd))
|
|
||||||
return;
|
|
||||||
|
|
||||||
QString q2 = this->findChild<QLineEdit*>(HexFindDialog::LEREPLACE)->text();
|
|
||||||
auto offset = this->hexView()->hexCursor()->replace(
|
|
||||||
q1, q2, m_startoffset > -1 ? m_startoffset : this->hexView()->offset(),
|
|
||||||
mode, m_findoptions, fd);
|
|
||||||
this->checkResult(q1, offset, fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HexFindDialog::find() {
|
|
||||||
QString q;
|
|
||||||
QHexFindMode mode;
|
|
||||||
QHexFindDirection fd;
|
|
||||||
|
|
||||||
if(!this->prepareOptions(q, mode, fd))
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto offset = this->hexView()->hexCursor()->find(
|
|
||||||
q, m_startoffset > -1 ? m_startoffset : this->hexView()->offset(), mode,
|
|
||||||
m_findoptions, fd);
|
|
||||||
this->checkResult(q, offset, fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HexFindDialog::prepareOptions(QString& q, QHexFindMode& mode,
|
|
||||||
QHexFindDirection& fd) {
|
|
||||||
q = this->findChild<QLineEdit*>(HexFindDialog::LEFIND)->text();
|
|
||||||
mode = static_cast<QHexFindMode>(
|
|
||||||
this->findChild<QComboBox*>(HexFindDialog::CBFINDMODE)
|
|
||||||
->currentData()
|
|
||||||
.toUInt());
|
|
||||||
|
|
||||||
if(mode == QHexFindMode::Hex && !QHexUtils::checkPattern(q)) {
|
|
||||||
QMessageBox::warning(this, tr("Pattern Error"),
|
|
||||||
tr("Hex pattern '%1' is not valid").arg(q));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this->findChild<QRadioButton*>(HexFindDialog::RBBACKWARD)->isChecked())
|
|
||||||
fd = QHexFindDirection::Backward;
|
|
||||||
else if(this->findChild<QRadioButton*>(HexFindDialog::RBFORWARD)
|
|
||||||
->isChecked())
|
|
||||||
fd = QHexFindDirection::Forward;
|
|
||||||
else
|
|
||||||
fd = QHexFindDirection::All;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HexFindDialog::prepareTextMode(QLayout* l) {
|
|
||||||
auto* cbcasesensitive = new QCheckBox("Case sensitive");
|
|
||||||
|
|
||||||
connect(cbcasesensitive, &QCheckBox::stateChanged, this, [this](int state) {
|
|
||||||
if(state == Qt::Checked)
|
|
||||||
m_findoptions |= QHexFindOptions::CaseSensitive;
|
|
||||||
else
|
|
||||||
m_findoptions &= ~QHexFindOptions::CaseSensitive;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto* vlayout = new QVBoxLayout(new QWidget());
|
|
||||||
vlayout->addWidget(cbcasesensitive);
|
|
||||||
l->addWidget(vlayout->parentWidget());
|
|
||||||
}
|
|
||||||
|
|
||||||
void HexFindDialog::prepareHexMode(QLayout* l) { l->addWidget(new QWidget()); }
|
|
||||||
|
|
||||||
void HexFindDialog::prepareIntMode(QLayout* l) {
|
|
||||||
static const QList<QPair<QString, unsigned int>> INT_TYPES = {
|
|
||||||
qMakePair<QString, unsigned int>("(any)", 0),
|
|
||||||
qMakePair<QString, unsigned int>("8", QHexFindOptions::Int8),
|
|
||||||
qMakePair<QString, unsigned int>("16", QHexFindOptions::Int16),
|
|
||||||
qMakePair<QString, unsigned int>("32", QHexFindOptions::Int32),
|
|
||||||
qMakePair<QString, unsigned int>("64", QHexFindOptions::Int64)};
|
|
||||||
|
|
||||||
auto* cbbits = new QComboBox();
|
|
||||||
for(const auto& it : INT_TYPES)
|
|
||||||
cbbits->addItem(it.first, it.second);
|
|
||||||
|
|
||||||
connect(cbbits, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
|
||||||
[this, cbbits](int index) {
|
|
||||||
if(m_oldidxbits > -1)
|
|
||||||
m_findoptions &= ~cbbits->itemData(m_oldidxbits).toUInt();
|
|
||||||
m_findoptions |= cbbits->itemData(index).toUInt();
|
|
||||||
m_oldidxbits = index;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto* cbendian = new QComboBox();
|
|
||||||
cbendian->addItem("Little Endian", 0);
|
|
||||||
cbendian->addItem("Big Endian", QHexFindOptions::BigEndian);
|
|
||||||
|
|
||||||
connect(cbendian, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
|
||||||
[this, cbendian](int index) {
|
|
||||||
if(m_oldidxendian > -1)
|
|
||||||
m_findoptions &=
|
|
||||||
~cbendian->itemData(m_oldidxendian).toUInt();
|
|
||||||
m_findoptions |= cbendian->itemData(index).toUInt();
|
|
||||||
m_oldidxendian = index;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto* vlayout = new QVBoxLayout(new QWidget());
|
|
||||||
|
|
||||||
QGridLayout* gl = new QGridLayout();
|
|
||||||
gl->addWidget(new QLabel("Type:"), 0, 0, Qt::AlignRight);
|
|
||||||
gl->addWidget(cbbits, 0, 1);
|
|
||||||
gl->addWidget(new QLabel("Endian:"), 1, 0, Qt::AlignRight);
|
|
||||||
gl->addWidget(cbendian, 1, 1);
|
|
||||||
vlayout->addLayout(gl);
|
|
||||||
|
|
||||||
l->addWidget(vlayout->parentWidget());
|
|
||||||
}
|
|
||||||
|
|
||||||
void HexFindDialog::prepareFloatMode(QLayout* l) {
|
|
||||||
static const QList<QPair<QString, unsigned int>> FLOAT_TYPES = {
|
|
||||||
qMakePair<QString, unsigned int>("float", QHexFindOptions::Float),
|
|
||||||
qMakePair<QString, unsigned int>("double", QHexFindOptions::Double)};
|
|
||||||
|
|
||||||
bool first = true;
|
|
||||||
auto* vlayout = new QVBoxLayout(new QWidget());
|
|
||||||
|
|
||||||
for(const auto& ft : FLOAT_TYPES) {
|
|
||||||
auto* rb = new QRadioButton(ft.first);
|
|
||||||
rb->setChecked(first);
|
|
||||||
vlayout->addWidget(rb);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
l->addWidget(vlayout->parentWidget());
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
#include <QFile>
|
|
||||||
#include <QHexView/model/buffer/qmappedfilebuffer.h>
|
|
||||||
|
|
||||||
QMappedFileBuffer::QMappedFileBuffer(QObject* parent): QDeviceBuffer{parent} {}
|
|
||||||
|
|
||||||
QMappedFileBuffer::~QMappedFileBuffer() {
|
|
||||||
if((m_device && (m_device->parent() == this)) && m_mappeddata) {
|
|
||||||
QFile* f = qobject_cast<QFile*>(m_device);
|
|
||||||
f->unmap(m_mappeddata);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_mappeddata = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray QMappedFileBuffer::read(qint64 offset, int length) {
|
|
||||||
if(offset >= this->length())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
if(offset + length >= this->length())
|
|
||||||
length = this->length() - offset;
|
|
||||||
|
|
||||||
return QByteArray::fromRawData(
|
|
||||||
reinterpret_cast<const char*>(m_mappeddata + offset), length);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QMappedFileBuffer::read(QIODevice* iodevice) {
|
|
||||||
m_device = qobject_cast<QFile*>(iodevice);
|
|
||||||
if(!m_device || !QDeviceBuffer::read(iodevice))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
this->remap();
|
|
||||||
return m_mappeddata;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMappedFileBuffer::write(QIODevice* iodevice) {
|
|
||||||
if(iodevice == m_device)
|
|
||||||
this->remap();
|
|
||||||
else
|
|
||||||
iodevice->write(reinterpret_cast<const char*>(m_mappeddata),
|
|
||||||
m_device->size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMappedFileBuffer::remap() {
|
|
||||||
QFile* f = qobject_cast<QFile*>(m_device);
|
|
||||||
if(!f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(m_mappeddata)
|
|
||||||
f->unmap(m_mappeddata);
|
|
||||||
m_mappeddata = f->map(0, f->size());
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
#include <QHexView/model/buffer/qmemorybuffer.h>
|
|
||||||
#include <QIODevice>
|
|
||||||
|
|
||||||
QMemoryBuffer::QMemoryBuffer(QObject* parent): QHexBuffer{parent} {}
|
|
||||||
|
|
||||||
uchar QMemoryBuffer::at(qint64 idx) {
|
|
||||||
return static_cast<uchar>(m_buffer.at(idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QMemoryBuffer::length() const {
|
|
||||||
return static_cast<qint64>(m_buffer.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMemoryBuffer::insert(qint64 offset, const QByteArray& data) {
|
|
||||||
m_buffer.insert(static_cast<int>(offset), data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMemoryBuffer::remove(qint64 offset, int length) {
|
|
||||||
m_buffer.remove(static_cast<int>(offset), length);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray QMemoryBuffer::read(qint64 offset, int length) {
|
|
||||||
return m_buffer.mid(static_cast<int>(offset), length);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QMemoryBuffer::read(QIODevice* device) {
|
|
||||||
m_buffer = device->readAll();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMemoryBuffer::write(QIODevice* device) { device->write(m_buffer); }
|
|
||||||
|
|
||||||
qint64 QMemoryBuffer::indexOf(const QByteArray& ba, qint64 from) {
|
|
||||||
return m_buffer.indexOf(ba, static_cast<int>(from));
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QMemoryBuffer::lastIndexOf(const QByteArray& ba, qint64 from) {
|
|
||||||
return m_buffer.lastIndexOf(ba, static_cast<int>(from));
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
#include <QBuffer>
|
|
||||||
#include <QHexView/model/buffer/qmemoryrefbuffer.h>
|
|
||||||
|
|
||||||
QMemoryRefBuffer::QMemoryRefBuffer(QObject* parent): QDeviceBuffer{parent} {}
|
|
||||||
|
|
||||||
bool QMemoryRefBuffer::read(QIODevice* device) {
|
|
||||||
m_device = qobject_cast<QBuffer*>(device);
|
|
||||||
|
|
||||||
if(m_device) {
|
|
||||||
m_device->setParent(this);
|
|
||||||
return QDeviceBuffer::read(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMemoryRefBuffer::write(QIODevice* device) {
|
|
||||||
if(!m_device || m_device == device)
|
|
||||||
return;
|
|
||||||
|
|
||||||
static const int CHUNK_SIZE = 4096;
|
|
||||||
m_device->seek(0);
|
|
||||||
|
|
||||||
while(!m_device->atEnd())
|
|
||||||
device->write(m_device->read(CHUNK_SIZE));
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
#include <QHexView/model/commands/hexcommand.h>
|
|
||||||
|
|
||||||
HexCommand::HexCommand(QHexBuffer* buffer, QHexDocument* document,
|
|
||||||
QUndoCommand* parent)
|
|
||||||
: QUndoCommand(parent), m_hexdocument(document), m_buffer(buffer),
|
|
||||||
m_offset(0), m_length(0) {}
|
|
|
@ -1,18 +0,0 @@
|
||||||
#include <QHexView/model/commands/insertcommand.h>
|
|
||||||
#include <QHexView/model/qhexdocument.h>
|
|
||||||
|
|
||||||
InsertCommand::InsertCommand(QHexBuffer* buffer, QHexDocument* document,
|
|
||||||
qint64 offset, const QByteArray& data,
|
|
||||||
QUndoCommand* parent)
|
|
||||||
: HexCommand(buffer, document, parent) {
|
|
||||||
m_offset = offset;
|
|
||||||
m_data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InsertCommand::undo() {
|
|
||||||
m_buffer->remove(m_offset, m_data.length());
|
|
||||||
Q_EMIT m_hexdocument->dataChanged(m_data, m_offset,
|
|
||||||
QHexDocument::ChangeReason::Remove);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InsertCommand::redo() { m_buffer->insert(m_offset, m_data); }
|
|
|
@ -1,20 +0,0 @@
|
||||||
#include <QHexView/model/commands/removecommand.h>
|
|
||||||
#include <QHexView/model/qhexdocument.h>
|
|
||||||
|
|
||||||
RemoveCommand::RemoveCommand(QHexBuffer* buffer, QHexDocument* document,
|
|
||||||
qint64 offset, int length, QUndoCommand* parent)
|
|
||||||
: HexCommand(buffer, document, parent) {
|
|
||||||
m_offset = offset;
|
|
||||||
m_length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveCommand::undo() {
|
|
||||||
m_buffer->insert(m_offset, m_data);
|
|
||||||
Q_EMIT m_hexdocument->dataChanged(m_data, m_offset,
|
|
||||||
QHexDocument::ChangeReason::Insert);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveCommand::redo() {
|
|
||||||
m_data = m_buffer->read(m_offset, m_length); // Backup data
|
|
||||||
m_buffer->remove(m_offset, m_length);
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
#include <QHexView/model/commands/replacecommand.h>
|
|
||||||
#include <QHexView/model/qhexdocument.h>
|
|
||||||
|
|
||||||
ReplaceCommand::ReplaceCommand(QHexBuffer* buffer, QHexDocument* document,
|
|
||||||
qint64 offset, const QByteArray& data,
|
|
||||||
QUndoCommand* parent)
|
|
||||||
: HexCommand(buffer, document, parent) {
|
|
||||||
m_offset = offset;
|
|
||||||
m_data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReplaceCommand::undo() {
|
|
||||||
m_buffer->replace(m_offset, m_olddata);
|
|
||||||
Q_EMIT m_hexdocument->dataChanged(m_olddata, m_offset,
|
|
||||||
QHexDocument::ChangeReason::Replace);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReplaceCommand::redo() {
|
|
||||||
m_olddata = m_buffer->read(m_offset, m_data.length());
|
|
||||||
m_buffer->replace(m_offset, m_data);
|
|
||||||
}
|
|
|
@ -1,182 +0,0 @@
|
||||||
#include <QHexView/model/qhexcursor.h>
|
|
||||||
#include <QHexView/model/qhexdocument.h>
|
|
||||||
#include <QHexView/qhexview.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* https://stackoverflow.com/questions/10803043/inverse-column-row-major-order-transformation
|
|
||||||
*
|
|
||||||
* If the index is calculated as:
|
|
||||||
* offset = row + column*NUMROWS
|
|
||||||
* then the inverse would be:
|
|
||||||
* row = offset % NUMROWS
|
|
||||||
* column = offset / NUMROWS
|
|
||||||
* where % is modulus, and / is integer division.
|
|
||||||
*/
|
|
||||||
|
|
||||||
QHexCursor::QHexCursor(const QHexOptions* options, QHexView* parent)
|
|
||||||
: QObject(parent), m_options(options) {}
|
|
||||||
|
|
||||||
QHexView* QHexCursor::hexView() const {
|
|
||||||
return qobject_cast<QHexView*>(this->parent());
|
|
||||||
}
|
|
||||||
|
|
||||||
QHexCursor::Mode QHexCursor::mode() const { return m_mode; }
|
|
||||||
qint64 QHexCursor::offset() const { return this->positionToOffset(m_position); }
|
|
||||||
|
|
||||||
qint64 QHexCursor::address() const {
|
|
||||||
return m_options->baseaddress + this->offset();
|
|
||||||
}
|
|
||||||
|
|
||||||
quint64 QHexCursor::lineAddress() const {
|
|
||||||
return m_options->baseaddress + (m_position.line * m_options->linelength);
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QHexCursor::selectionStartOffset() const {
|
|
||||||
return this->positionToOffset(this->selectionStart());
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QHexCursor::selectionEndOffset() const {
|
|
||||||
return this->positionToOffset(this->selectionEnd());
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QHexCursor::line() const { return m_position.line; }
|
|
||||||
qint64 QHexCursor::column() const { return m_position.column; }
|
|
||||||
|
|
||||||
QHexPosition QHexCursor::selectionStart() const {
|
|
||||||
if(m_position.line < m_selection.line)
|
|
||||||
return m_position;
|
|
||||||
|
|
||||||
if(m_position.line == m_selection.line) {
|
|
||||||
if(m_position.column < m_selection.column)
|
|
||||||
return m_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_selection;
|
|
||||||
}
|
|
||||||
|
|
||||||
QHexPosition QHexCursor::selectionEnd() const {
|
|
||||||
if(m_position.line > m_selection.line)
|
|
||||||
return m_position;
|
|
||||||
|
|
||||||
if(m_position.line == m_selection.line) {
|
|
||||||
if(m_position.column > m_selection.column)
|
|
||||||
return m_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_selection;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QHexCursor::selectionLength() const {
|
|
||||||
auto selstart = this->selectionStartOffset(),
|
|
||||||
selend = this->selectionEndOffset();
|
|
||||||
return selstart == selend ? 0 : selend - selstart + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
QHexPosition QHexCursor::position() const { return m_position; }
|
|
||||||
|
|
||||||
QByteArray QHexCursor::selectedBytes() const {
|
|
||||||
return this->hexView()->selectedBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QHexCursor::hasSelection() const { return m_position != m_selection; }
|
|
||||||
|
|
||||||
bool QHexCursor::isSelected(qint64 line, qint64 column) const {
|
|
||||||
if(!this->hasSelection())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto selstart = this->selectionStart(), selend = this->selectionEnd();
|
|
||||||
if(line > selstart.line && line < selend.line)
|
|
||||||
return true;
|
|
||||||
if(line == selstart.line && line == selend.line)
|
|
||||||
return column >= selstart.column && column <= selend.column;
|
|
||||||
if(line == selstart.line)
|
|
||||||
return column >= selstart.column;
|
|
||||||
if(line == selend.line)
|
|
||||||
return column <= selend.column;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexCursor::setMode(Mode m) {
|
|
||||||
if(m_mode == m)
|
|
||||||
return;
|
|
||||||
m_mode = m;
|
|
||||||
Q_EMIT modeChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexCursor::switchMode() {
|
|
||||||
switch(m_mode) {
|
|
||||||
case Mode::Insert: this->setMode(Mode::Overwrite); break;
|
|
||||||
case Mode::Overwrite: this->setMode(Mode::Insert); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexCursor::move(qint64 offset) {
|
|
||||||
this->move(this->offsetToPosition(offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexCursor::move(qint64 line, qint64 column) {
|
|
||||||
return this->move({line, column});
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexCursor::move(QHexPosition pos) {
|
|
||||||
if(pos.line >= 0)
|
|
||||||
m_selection.line = pos.line;
|
|
||||||
if(pos.column >= 0)
|
|
||||||
m_selection.column = pos.column;
|
|
||||||
this->select(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexCursor::select(qint64 offset) {
|
|
||||||
this->select(this->offsetToPosition(offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexCursor::select(qint64 line, qint64 column) {
|
|
||||||
this->select({line, column});
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexCursor::select(QHexPosition pos) {
|
|
||||||
if(pos.line >= 0)
|
|
||||||
m_position.line = pos.line;
|
|
||||||
if(pos.column >= 0)
|
|
||||||
m_position.column = pos.column;
|
|
||||||
Q_EMIT positionChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexCursor::selectSize(qint64 length) {
|
|
||||||
if(length > 0)
|
|
||||||
length--;
|
|
||||||
else if(length < 0)
|
|
||||||
length++;
|
|
||||||
if(length)
|
|
||||||
this->select(this->offset() + length);
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QHexCursor::replace(const QVariant& oldvalue, const QVariant& newvalue,
|
|
||||||
qint64 offset, QHexFindMode mode,
|
|
||||||
unsigned int options, QHexFindDirection fd) const {
|
|
||||||
return this->hexView()->replace(oldvalue, newvalue, offset, mode, options,
|
|
||||||
fd);
|
|
||||||
}
|
|
||||||
qint64 QHexCursor::find(const QVariant& value, qint64 offset, QHexFindMode mode,
|
|
||||||
unsigned int options, QHexFindDirection fd) const {
|
|
||||||
return this->hexView()->find(value, offset, mode, options, fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexCursor::cut(bool hex) { this->hexView()->cut(hex); }
|
|
||||||
void QHexCursor::copy(bool hex) const { this->hexView()->copy(hex); }
|
|
||||||
void QHexCursor::paste(bool hex) { this->hexView()->paste(hex); }
|
|
||||||
void QHexCursor::selectAll() { this->hexView()->selectAll(); }
|
|
||||||
void QHexCursor::removeSelection() { this->hexView()->removeSelection(); }
|
|
||||||
|
|
||||||
void QHexCursor::clearSelection() {
|
|
||||||
m_position = m_selection;
|
|
||||||
Q_EMIT positionChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QHexCursor::positionToOffset(QHexPosition pos) const {
|
|
||||||
return QHexUtils::positionToOffset(m_options, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
QHexPosition QHexCursor::offsetToPosition(qint64 offset) const {
|
|
||||||
return QHexUtils::offsetToPosition(m_options, offset);
|
|
||||||
}
|
|
|
@ -1,142 +0,0 @@
|
||||||
#include <QBuffer>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QHexView/model/buffer/qdevicebuffer.h>
|
|
||||||
#include <QHexView/model/buffer/qmappedfilebuffer.h>
|
|
||||||
#include <QHexView/model/buffer/qmemorybuffer.h>
|
|
||||||
#include <QHexView/model/commands/insertcommand.h>
|
|
||||||
#include <QHexView/model/commands/removecommand.h>
|
|
||||||
#include <QHexView/model/commands/replacecommand.h>
|
|
||||||
#include <QHexView/model/qhexdocument.h>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
QHexDocument::QHexDocument(QHexBuffer* buffer, QObject* parent)
|
|
||||||
: QObject(parent) {
|
|
||||||
m_buffer = buffer;
|
|
||||||
m_buffer->setParent(this); // Take Ownership
|
|
||||||
|
|
||||||
connect(&m_undostack, &QUndoStack::canUndoChanged, this,
|
|
||||||
&QHexDocument::canUndoChanged);
|
|
||||||
connect(&m_undostack, &QUndoStack::canRedoChanged, this,
|
|
||||||
&QHexDocument::canRedoChanged);
|
|
||||||
connect(&m_undostack, &QUndoStack::cleanChanged, this,
|
|
||||||
[&](bool clean) { Q_EMIT modifiedChanged(!clean); });
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QHexDocument::indexOf(const QByteArray& ba, qint64 from) {
|
|
||||||
return m_buffer->indexOf(ba, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QHexDocument::lastIndexOf(const QByteArray& ba, qint64 from) {
|
|
||||||
return m_buffer->lastIndexOf(ba, from);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QHexDocument::accept(qint64 idx) const { return m_buffer->accept(idx); }
|
|
||||||
bool QHexDocument::isEmpty() const { return m_buffer->isEmpty(); }
|
|
||||||
bool QHexDocument::isModified() const { return !m_undostack.isClean(); }
|
|
||||||
bool QHexDocument::canUndo() const { return m_undostack.canUndo(); }
|
|
||||||
bool QHexDocument::canRedo() const { return m_undostack.canRedo(); }
|
|
||||||
|
|
||||||
void QHexDocument::setData(const QByteArray& ba) {
|
|
||||||
QHexBuffer* mb = new QMemoryBuffer();
|
|
||||||
mb->read(ba);
|
|
||||||
this->setData(mb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexDocument::setData(QHexBuffer* buffer) {
|
|
||||||
if(!buffer)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_undostack.clear();
|
|
||||||
buffer->setParent(this);
|
|
||||||
|
|
||||||
auto* oldbuffer = m_buffer;
|
|
||||||
m_buffer = buffer;
|
|
||||||
if(oldbuffer)
|
|
||||||
oldbuffer->deleteLater();
|
|
||||||
|
|
||||||
Q_EMIT canUndoChanged(false);
|
|
||||||
Q_EMIT canRedoChanged(false);
|
|
||||||
Q_EMIT changed();
|
|
||||||
Q_EMIT reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexDocument::clearModified() { m_undostack.setClean(); }
|
|
||||||
|
|
||||||
qint64 QHexDocument::length() const {
|
|
||||||
return m_buffer ? m_buffer->length() : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uchar QHexDocument::at(int offset) const { return m_buffer->at(offset); }
|
|
||||||
|
|
||||||
QHexDocument* QHexDocument::fromFile(QString filename, QObject* parent) {
|
|
||||||
QFile f(filename);
|
|
||||||
f.open(QFile::ReadOnly);
|
|
||||||
return QHexDocument::fromMemory<QMemoryBuffer>(f.readAll(), parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexDocument::undo() {
|
|
||||||
m_undostack.undo();
|
|
||||||
Q_EMIT changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexDocument::redo() {
|
|
||||||
m_undostack.redo();
|
|
||||||
Q_EMIT changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexDocument::insert(qint64 offset, uchar b) {
|
|
||||||
this->insert(offset, QByteArray(1, b));
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexDocument::replace(qint64 offset, uchar b) {
|
|
||||||
this->replace(offset, QByteArray(1, b));
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexDocument::insert(qint64 offset, const QByteArray& data) {
|
|
||||||
m_undostack.push(new InsertCommand(m_buffer, this, offset, data));
|
|
||||||
|
|
||||||
Q_EMIT changed();
|
|
||||||
Q_EMIT dataChanged(data, offset, ChangeReason::Insert);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexDocument::replace(qint64 offset, const QByteArray& data) {
|
|
||||||
m_undostack.push(new ReplaceCommand(m_buffer, this, offset, data));
|
|
||||||
Q_EMIT changed();
|
|
||||||
Q_EMIT dataChanged(data, offset, ChangeReason::Replace);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexDocument::remove(qint64 offset, int len) {
|
|
||||||
QByteArray data = m_buffer->read(offset, len);
|
|
||||||
|
|
||||||
m_undostack.push(new RemoveCommand(m_buffer, this, offset, len));
|
|
||||||
Q_EMIT changed();
|
|
||||||
Q_EMIT dataChanged(data, offset, ChangeReason::Remove);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray QHexDocument::read(qint64 offset, int len) const {
|
|
||||||
return m_buffer->read(offset, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QHexDocument::saveTo(QIODevice* device) {
|
|
||||||
if(!device->isWritable())
|
|
||||||
return false;
|
|
||||||
m_buffer->write(device);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QHexDocument* QHexDocument::fromBuffer(QHexBuffer* buffer, QObject* parent) {
|
|
||||||
return new QHexDocument(buffer, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
QHexDocument* QHexDocument::fromLargeFile(QString filename, QObject* parent) {
|
|
||||||
return QHexDocument::fromDevice<QDeviceBuffer>(new QFile(filename), parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
QHexDocument* QHexDocument::fromMappedFile(QString filename, QObject* parent) {
|
|
||||||
return QHexDocument::fromDevice<QMappedFileBuffer>(new QFile(filename),
|
|
||||||
parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
QHexDocument* QHexDocument::create(QObject* parent) {
|
|
||||||
return QHexDocument::fromMemory<QMemoryBuffer>({}, parent);
|
|
||||||
}
|
|
|
@ -1,384 +0,0 @@
|
||||||
#include <QDataStream>
|
|
||||||
#include <QGlobalStatic>
|
|
||||||
#include <QHash>
|
|
||||||
#include <QHexView/model/qhexoptions.h>
|
|
||||||
#include <QHexView/model/qhexutils.h>
|
|
||||||
#include <QHexView/qhexview.h>
|
|
||||||
#include <QList>
|
|
||||||
#include <QtEndian>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
#define QHEXVIEW_VARIANT_EQ(x, t) ((x).metaType().id() == QMetaType::Q##t)
|
|
||||||
#else
|
|
||||||
#define QHEXVIEW_VARIANT_EQ(x, t) ((x).type() == QVariant::t)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32) && _MSC_VER <= 1916 // v141_xp
|
|
||||||
#include <ctype.h>
|
|
||||||
namespace std {
|
|
||||||
using ::tolower;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#include <cctype>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace QHexUtils {
|
|
||||||
|
|
||||||
Q_GLOBAL_STATIC_WITH_ARGS(QList<char>, HEXMAP,
|
|
||||||
({'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
|
||||||
'a', 'b', 'c', 'd', 'e', 'f'}));
|
|
||||||
|
|
||||||
bool isHex(char ch) {
|
|
||||||
return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') ||
|
|
||||||
(ch >= 'a' && ch <= 'f');
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace PatternUtils {
|
|
||||||
|
|
||||||
Q_GLOBAL_STATIC_WITH_ARGS(QString, WILDCARD_BYTE, ("??"))
|
|
||||||
|
|
||||||
bool check(QString& p, qint64& len) {
|
|
||||||
static QHash<QString, QPair<QString, size_t>>
|
|
||||||
processed; // Cache processed patterns
|
|
||||||
|
|
||||||
auto it = processed.find(p);
|
|
||||||
|
|
||||||
if(it != processed.end()) {
|
|
||||||
p = it.value().first;
|
|
||||||
len = it.value().second;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString op = p; // Store unprocessed pattern
|
|
||||||
p = p.simplified().replace(" ", "");
|
|
||||||
if(p.isEmpty() || (p.size() % 2))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int wccount = 0;
|
|
||||||
|
|
||||||
for(auto i = 0; i < p.size() - 2; i += 2) {
|
|
||||||
const auto& hexb = p.mid(i, 2);
|
|
||||||
|
|
||||||
if(hexb == *WILDCARD_BYTE) {
|
|
||||||
wccount++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!QHexUtils::isHex(hexb.at(0).toLatin1()) ||
|
|
||||||
!QHexUtils::isHex(hexb.at(1).toLatin1()))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(wccount >= p.size())
|
|
||||||
return false;
|
|
||||||
len = p.size() / 2;
|
|
||||||
processed[op] = qMakePair(p, len); // Cache processed pattern
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool match(const QByteArray& data, const QString& pattern) {
|
|
||||||
for(qint64 i = 0, idx = 0; (i <= (pattern.size() - 2)); i += 2, idx++) {
|
|
||||||
if(idx >= data.size())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
QStringView hexb = QStringView{pattern}.mid(i, 2);
|
|
||||||
#else
|
|
||||||
const QStringRef& hexb = pattern.midRef(i, 2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(hexb == *WILDCARD_BYTE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
bool ok = false;
|
|
||||||
auto b = static_cast<char>(hexb.toUInt(&ok, 16));
|
|
||||||
if(!ok || (b != data.at(idx)))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace PatternUtils
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
unsigned int countBits(uint val) {
|
|
||||||
if(val <= std::numeric_limits<quint8>::max())
|
|
||||||
return QHexFindOptions::Int8;
|
|
||||||
if(val <= std::numeric_limits<quint16>::max())
|
|
||||||
return QHexFindOptions::Int16;
|
|
||||||
if(val <= std::numeric_limits<quint32>::max())
|
|
||||||
return QHexFindOptions::Int32;
|
|
||||||
|
|
||||||
return QHexFindOptions::Int64;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Function>
|
|
||||||
qint64 findIter(qint64 startoffset, QHexFindDirection fd,
|
|
||||||
const QHexView* hexview, Function&& f) {
|
|
||||||
QHexDocument* hexdocument = hexview->hexDocument();
|
|
||||||
qint64 offset = -1;
|
|
||||||
|
|
||||||
QHexFindDirection cfd = fd;
|
|
||||||
if(cfd == QHexFindDirection::All)
|
|
||||||
cfd = QHexFindDirection::Forward;
|
|
||||||
|
|
||||||
qint64 i = startoffset;
|
|
||||||
|
|
||||||
bool restartLoopOnce = true;
|
|
||||||
|
|
||||||
while(offset == -1 &&
|
|
||||||
(cfd == QHexFindDirection::Backward ? (i >= 0)
|
|
||||||
: (i < hexdocument->length()))) {
|
|
||||||
if(!f(i, offset))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(cfd == QHexFindDirection::Backward)
|
|
||||||
i--;
|
|
||||||
else
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if(fd == QHexFindDirection::All && i >= hexdocument->length() &&
|
|
||||||
restartLoopOnce) {
|
|
||||||
i = 0;
|
|
||||||
restartLoopOnce = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 findDefault(const QByteArray& value, qint64 startoffset,
|
|
||||||
const QHexView* hexview, unsigned int options,
|
|
||||||
QHexFindDirection fd) {
|
|
||||||
QHexDocument* hexdocument = hexview->hexDocument();
|
|
||||||
if(value.size() > hexdocument->length())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return findIter(
|
|
||||||
startoffset, fd, hexview,
|
|
||||||
[options, value, hexdocument](qint64 idx, qint64& offset) -> bool {
|
|
||||||
for(auto i = 0; i < value.size(); i++) {
|
|
||||||
qint64 curroffset = idx + i;
|
|
||||||
|
|
||||||
if(curroffset >= hexdocument->length()) {
|
|
||||||
offset = -1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uchar ch1 = hexdocument->at(curroffset);
|
|
||||||
uchar ch2 = value.at(i);
|
|
||||||
|
|
||||||
if(!(options & QHexFindOptions::CaseSensitive)) {
|
|
||||||
ch1 = std::tolower(ch1);
|
|
||||||
ch2 = std::tolower(ch2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ch1 != ch2)
|
|
||||||
break;
|
|
||||||
if(i == value.size() - 1)
|
|
||||||
offset = idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 findWildcard(QString pattern, qint64 startoffset,
|
|
||||||
const QHexView* hexview, QHexFindDirection fd,
|
|
||||||
qint64& patternlen) {
|
|
||||||
QHexDocument* hexdocument = hexview->hexDocument();
|
|
||||||
if(!PatternUtils::check(pattern, patternlen) ||
|
|
||||||
(patternlen >= hexdocument->length()))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return findIter(
|
|
||||||
startoffset, fd, hexview,
|
|
||||||
[hexdocument, pattern, patternlen](qint64 idx, qint64& offset) -> bool {
|
|
||||||
if(PatternUtils::match(hexdocument->read(idx, patternlen), pattern))
|
|
||||||
offset = idx;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray variantToByteArray(QVariant value, QHexFindMode mode,
|
|
||||||
unsigned int options) {
|
|
||||||
QByteArray v;
|
|
||||||
|
|
||||||
switch(mode) {
|
|
||||||
case QHexFindMode::Text:
|
|
||||||
if(QHEXVIEW_VARIANT_EQ(value, String))
|
|
||||||
v = value.toString().toUtf8();
|
|
||||||
else if(QHEXVIEW_VARIANT_EQ(value, ByteArray))
|
|
||||||
v = value.toByteArray();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QHexFindMode::Hex: {
|
|
||||||
if(QHEXVIEW_VARIANT_EQ(value, String)) {
|
|
||||||
qint64 len = 0;
|
|
||||||
auto s = value.toString();
|
|
||||||
if(!PatternUtils::check(s, len))
|
|
||||||
return {};
|
|
||||||
|
|
||||||
bool ok = true;
|
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
||||||
for(auto i = 0; ok && i < s.size(); i += 2)
|
|
||||||
v.push_back(static_cast<char>(
|
|
||||||
QStringView{s}.mid(i, 2).toUInt(&ok, 16)));
|
|
||||||
#else
|
|
||||||
for(auto i = 0; ok && i < s.size(); i += 2)
|
|
||||||
v.push_back(
|
|
||||||
static_cast<char>(s.midRef(i, 2).toUInt(&ok, 16)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!ok)
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
else if(QHEXVIEW_VARIANT_EQ(value, ByteArray))
|
|
||||||
v = value.toByteArray();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case QHexFindMode::Int: {
|
|
||||||
bool ok = false;
|
|
||||||
uint val = value.toUInt(&ok);
|
|
||||||
if(!ok)
|
|
||||||
return QByteArray{};
|
|
||||||
|
|
||||||
QDataStream ds(&v, QIODevice::WriteOnly);
|
|
||||||
|
|
||||||
if(options & QHexFindOptions::BigEndian) {
|
|
||||||
if(options & QHexFindOptions::Int8)
|
|
||||||
ds << qToBigEndian<quint8>(val);
|
|
||||||
else if(options & QHexFindOptions::Int16)
|
|
||||||
ds << qToBigEndian<quint16>(val);
|
|
||||||
else if(options & QHexFindOptions::Int32)
|
|
||||||
ds << qToBigEndian<quint32>(val);
|
|
||||||
else if(options & QHexFindOptions::Int64)
|
|
||||||
ds << qToBigEndian<quint64>(val);
|
|
||||||
else
|
|
||||||
return variantToByteArray(value, mode,
|
|
||||||
options | countBits(val));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(options & QHexFindOptions::Int8)
|
|
||||||
ds << static_cast<quint8>(val);
|
|
||||||
else if(options & QHexFindOptions::Int16)
|
|
||||||
ds << static_cast<quint16>(val);
|
|
||||||
else if(options & QHexFindOptions::Int32)
|
|
||||||
ds << static_cast<quint32>(val);
|
|
||||||
else if(options & QHexFindOptions::Int64)
|
|
||||||
ds << static_cast<quint64>(val);
|
|
||||||
else
|
|
||||||
return variantToByteArray(value, mode,
|
|
||||||
options | countBits(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case QHexFindMode::Float: {
|
|
||||||
bool ok = false;
|
|
||||||
QDataStream ds(&v, QIODevice::WriteOnly);
|
|
||||||
if(options & QHexFindOptions::Float)
|
|
||||||
ds << value.toFloat(&ok);
|
|
||||||
else if(options & QHexFindOptions::Double)
|
|
||||||
ds << value.toDouble(&ok);
|
|
||||||
if(!ok)
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
QByteArray toHex(const QByteArray& ba, char sep) {
|
|
||||||
if(ba.isEmpty()) {
|
|
||||||
return QByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray hex(sep ? (ba.size() * 3 - 1) : (ba.size() * 2),
|
|
||||||
Qt::Uninitialized);
|
|
||||||
|
|
||||||
for(auto i = 0, o = 0; i < ba.size(); i++) {
|
|
||||||
if(sep && i)
|
|
||||||
hex[o++] = static_cast<uchar>(sep);
|
|
||||||
hex[o++] = HEXMAP->at((ba.at(i) & 0xf0) >> 4);
|
|
||||||
hex[o++] = HEXMAP->at(ba.at(i) & 0x0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hex;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray toHex(const QByteArray& ba) { return QHexUtils::toHex(ba, '\0'); }
|
|
||||||
qint64 positionToOffset(const QHexOptions* options, QHexPosition pos) {
|
|
||||||
return options->linelength * pos.line + pos.column;
|
|
||||||
}
|
|
||||||
QHexPosition offsetToPosition(const QHexOptions* options, qint64 offset) {
|
|
||||||
return {offset / options->linelength, offset % options->linelength};
|
|
||||||
}
|
|
||||||
|
|
||||||
QPair<qint64, qint64> find(const QHexView* hexview, QVariant value,
|
|
||||||
qint64 startoffset, QHexFindMode mode,
|
|
||||||
unsigned int options, QHexFindDirection fd) {
|
|
||||||
qint64 offset = -1, size = 0;
|
|
||||||
if(startoffset == -1)
|
|
||||||
startoffset = static_cast<qint64>(hexview->offset());
|
|
||||||
|
|
||||||
if(mode == QHexFindMode::Hex && QHEXVIEW_VARIANT_EQ(value, String)) {
|
|
||||||
offset = QHexUtils::findWildcard(value.toString(), startoffset, hexview,
|
|
||||||
fd, size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
auto ba = variantToByteArray(value, mode, options);
|
|
||||||
|
|
||||||
if(!ba.isEmpty()) {
|
|
||||||
offset =
|
|
||||||
QHexUtils::findDefault(ba, startoffset, hexview, options, fd);
|
|
||||||
size = ba.size();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
offset = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {offset, offset > -1 ? size : 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool checkPattern(QString pattern) {
|
|
||||||
qint64 len = 0;
|
|
||||||
return PatternUtils::check(pattern, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPair<qint64, qint64> replace(const QHexView* hexview, QVariant oldvalue,
|
|
||||||
QVariant newvalue, qint64 startoffset,
|
|
||||||
QHexFindMode mode, unsigned int options,
|
|
||||||
QHexFindDirection fd) {
|
|
||||||
auto res =
|
|
||||||
QHexUtils::find(hexview, oldvalue, startoffset, mode, options, fd);
|
|
||||||
|
|
||||||
if(res.first != -1 && res.second > 0) {
|
|
||||||
QHexDocument* hexdocument = hexview->hexDocument();
|
|
||||||
auto ba = variantToByteArray(newvalue, mode, options);
|
|
||||||
|
|
||||||
if(!ba.isEmpty()) {
|
|
||||||
hexdocument->remove(res.first, res.second);
|
|
||||||
hexdocument->insert(res.first, ba);
|
|
||||||
res.second = ba.size();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res.first = -1;
|
|
||||||
res.second = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace QHexUtils
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,14 +19,6 @@
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
USTATUS FfsFinder::findHexPattern(const UByteArray & hexPattern, const UINT8 mode) {
|
|
||||||
const UModelIndex rootIndex = model->index(0, 0);
|
|
||||||
USTATUS ret = findHexPattern(rootIndex, hexPattern, mode);
|
|
||||||
if (ret != U_SUCCESS)
|
|
||||||
msg(UString("Hex pattern \"") + UString(hexPattern) + UString("\" could not be found"), rootIndex);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode)
|
USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode)
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
|
@ -39,11 +31,9 @@ USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray &
|
||||||
if (hexPattern.count('.') == hexPattern.length())
|
if (hexPattern.count('.') == hexPattern.length())
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
|
|
||||||
USTATUS ret = U_ITEM_NOT_FOUND;
|
|
||||||
bool hasChildren = (model->rowCount(index) > 0);
|
bool hasChildren = (model->rowCount(index) > 0);
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
if (U_SUCCESS == findHexPattern(index.model()->index(i, index.column(), index), hexPattern, mode))
|
findHexPattern(index.model()->index(i, index.column(), index), hexPattern, mode);
|
||||||
ret = U_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UByteArray data;
|
UByteArray data;
|
||||||
|
@ -93,7 +83,6 @@ USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray &
|
||||||
+ UString("\" in ") + name
|
+ UString("\" in ") + name
|
||||||
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2),
|
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2),
|
||||||
index);
|
index);
|
||||||
ret = U_SUCCESS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,15 +93,7 @@ USTATUS FfsFinder::findHexPattern(const UModelIndex & index, const UByteArray &
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return U_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
USTATUS FfsFinder::findGuidPattern(const UByteArray & guidPattern, const UINT8 mode) {
|
|
||||||
const UModelIndex rootIndex = model->index(0, 0);
|
|
||||||
USTATUS ret = findGuidPattern(rootIndex, guidPattern, mode);
|
|
||||||
if (ret != U_SUCCESS)
|
|
||||||
msg(UString("GUID pattern \"") + UString(guidPattern) + UString("\" could not be found"), rootIndex);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode)
|
USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode)
|
||||||
|
@ -123,11 +104,9 @@ USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray &
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
|
|
||||||
USTATUS ret = U_ITEM_NOT_FOUND;
|
|
||||||
bool hasChildren = (model->rowCount(index) > 0);
|
bool hasChildren = (model->rowCount(index) > 0);
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
if (U_SUCCESS == findGuidPattern(index.model()->index(i, index.column(), index), guidPattern, mode))
|
findGuidPattern(index.model()->index(i, index.column(), index), guidPattern, mode);
|
||||||
ret = U_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UByteArray data;
|
UByteArray data;
|
||||||
|
@ -195,7 +174,6 @@ USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray &
|
||||||
+ UString("\" in ") + name
|
+ UString("\" in ") + name
|
||||||
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2),
|
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset / 2),
|
||||||
index);
|
index);
|
||||||
ret = U_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_VERSION_MAJOR >= 6
|
#if QT_VERSION_MAJOR >= 6
|
||||||
|
@ -205,16 +183,7 @@ USTATUS FfsFinder::findGuidPattern(const UModelIndex & index, const UByteArray &
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return U_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
USTATUS FfsFinder::findTextPattern(const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive) {
|
|
||||||
const UModelIndex rootIndex = model->index(0, 0);
|
|
||||||
USTATUS ret = findTextPattern(rootIndex, pattern, mode, unicode, caseSensitive);
|
|
||||||
if (ret != U_SUCCESS)
|
|
||||||
msg((unicode ? UString("Unicode") : UString("ASCII")) + UString(" text \"")
|
|
||||||
+ UString(pattern) + UString("\" could not be found"), rootIndex);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive)
|
USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive)
|
||||||
|
@ -225,11 +194,9 @@ USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pa
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
|
|
||||||
USTATUS ret = U_ITEM_NOT_FOUND;
|
|
||||||
bool hasChildren = (model->rowCount(index) > 0);
|
bool hasChildren = (model->rowCount(index) > 0);
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
if (U_SUCCESS == findTextPattern(index.model()->index(i, index.column(), index), pattern, mode, unicode, caseSensitive))
|
findTextPattern(index.model()->index(i, index.column(), index), pattern, mode, unicode, caseSensitive);
|
||||||
ret = U_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UByteArray body;
|
UByteArray body;
|
||||||
|
@ -269,8 +236,7 @@ USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pa
|
||||||
+ UString("\" found in ") + name
|
+ UString("\" found in ") + name
|
||||||
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset),
|
+ usprintf(" at %s-offset %02Xh", mode == SEARCH_MODE_BODY ? "body" : "header", offset),
|
||||||
index);
|
index);
|
||||||
ret = U_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,9 @@ public:
|
||||||
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
|
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
|
||||||
void clearMessages() { messagesVector.clear(); }
|
void clearMessages() { messagesVector.clear(); }
|
||||||
|
|
||||||
USTATUS findHexPattern(const UByteArray & hexPattern, const UINT8 mode);
|
USTATUS findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode);
|
||||||
USTATUS findGuidPattern(const UByteArray & guidPattern, const UINT8 mode);
|
USTATUS findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode);
|
||||||
USTATUS findTextPattern(const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive);
|
USTATUS findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const TreeModel* model;
|
const TreeModel* model;
|
||||||
|
@ -41,10 +41,6 @@ private:
|
||||||
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
|
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
|
||||||
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
|
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS findHexPattern(const UModelIndex & index, const UByteArray & hexPattern, const UINT8 mode);
|
|
||||||
USTATUS findGuidPattern(const UModelIndex & index, const UByteArray & guidPattern, const UINT8 mode);
|
|
||||||
USTATUS findTextPattern(const UModelIndex & index, const UString & pattern, const UINT8 mode, const bool unicode, const Qt::CaseSensitivity caseSensitive);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FFSFINDER_H
|
#endif // FFSFINDER_H
|
||||||
|
|
|
@ -1,16 +1,3 @@
|
||||||
/* gotoaddressdialog.h
|
|
||||||
|
|
||||||
Copyright (c) 2018, Nikolaj Schlej. All rights reserved.
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GOTOADDRESSDIALOG_H
|
#ifndef GOTOADDRESSDIALOG_H
|
||||||
#define GOTOADDRESSDIALOG_H
|
#define GOTOADDRESSDIALOG_H
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,3 @@
|
||||||
/* gotobasedialog.h
|
|
||||||
|
|
||||||
Copyright (c) 2018, Nikolaj Schlej. All rights reserved.
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GOTOBASEDIALOG_H
|
#ifndef GOTOBASEDIALOG_H
|
||||||
#define GOTOBASEDIALOG_H
|
#define GOTOBASEDIALOG_H
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
#define HEXVIEWDIALOG_H
|
#define HEXVIEWDIALOG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QHexView/qhexview.h>
|
|
||||||
#include "../common/treemodel.h"
|
#include "../common/treemodel.h"
|
||||||
|
#include "qhexview5/qhexview.h"
|
||||||
#include "ui_hexviewdialog.h"
|
#include "ui_hexviewdialog.h"
|
||||||
|
|
||||||
class HexViewDialog : public QDialog
|
class HexViewDialog : public QDialog
|
||||||
|
|
|
@ -1,23 +1,24 @@
|
||||||
#include <QHexView/model/buffer/qdevicebuffer.h>
|
#include "qdevicebuffer.h"
|
||||||
#include <QIODevice>
|
#include <QIODevice>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
QDeviceBuffer::QDeviceBuffer(QObject* parent): QHexBuffer{parent} {}
|
QDeviceBuffer::QDeviceBuffer(QObject *parent) : QHexBuffer{parent} { }
|
||||||
|
|
||||||
QDeviceBuffer::~QDeviceBuffer() {
|
QDeviceBuffer::~QDeviceBuffer()
|
||||||
if(!m_device)
|
{
|
||||||
return;
|
if(!m_device) return;
|
||||||
|
|
||||||
if(m_device->parent() == this) {
|
if(m_device->parent() == this)
|
||||||
if(m_device->isOpen())
|
{
|
||||||
m_device->close();
|
if(m_device->isOpen()) m_device->close();
|
||||||
m_device->deleteLater();
|
m_device->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_device = nullptr;
|
m_device = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar QDeviceBuffer::at(qint64 idx) {
|
uchar QDeviceBuffer::at(qint64 idx)
|
||||||
|
{
|
||||||
m_device->seek(idx);
|
m_device->seek(idx);
|
||||||
|
|
||||||
char c = '\0';
|
char c = '\0';
|
||||||
|
@ -27,61 +28,68 @@ uchar QDeviceBuffer::at(qint64 idx) {
|
||||||
|
|
||||||
qint64 QDeviceBuffer::length() const { return m_device->size(); }
|
qint64 QDeviceBuffer::length() const { return m_device->size(); }
|
||||||
|
|
||||||
void QDeviceBuffer::insert(qint64 offset, const QByteArray& data) {
|
void QDeviceBuffer::insert(qint64 offset, const QByteArray &data)
|
||||||
|
{
|
||||||
Q_UNUSED(offset)
|
Q_UNUSED(offset)
|
||||||
Q_UNUSED(data)
|
Q_UNUSED(data)
|
||||||
// Not implemented
|
// Not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
void QDeviceBuffer::replace(qint64 offset, const QByteArray& data) {
|
void QDeviceBuffer::replace(qint64 offset, const QByteArray& data)
|
||||||
|
{
|
||||||
m_device->seek(offset);
|
m_device->seek(offset);
|
||||||
m_device->write(data);
|
m_device->write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QDeviceBuffer::remove(qint64 offset, int length) {
|
void QDeviceBuffer::remove(qint64 offset, int length)
|
||||||
|
{
|
||||||
Q_UNUSED(offset)
|
Q_UNUSED(offset)
|
||||||
Q_UNUSED(length)
|
Q_UNUSED(length)
|
||||||
// Not implemented
|
// Not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray QDeviceBuffer::read(qint64 offset, int length) {
|
QByteArray QDeviceBuffer::read(qint64 offset, int length)
|
||||||
|
{
|
||||||
m_device->seek(offset);
|
m_device->seek(offset);
|
||||||
return m_device->read(length);
|
return m_device->read(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QDeviceBuffer::read(QIODevice* device) {
|
bool QDeviceBuffer::read(QIODevice *device)
|
||||||
|
{
|
||||||
m_device = device;
|
m_device = device;
|
||||||
if(!m_device)
|
if(!m_device) return false;
|
||||||
return false;
|
if(!m_device->isOpen()) m_device->open(QIODevice::ReadWrite);
|
||||||
if(!m_device->isOpen())
|
|
||||||
m_device->open(QIODevice::ReadWrite);
|
|
||||||
return m_device->isOpen();
|
return m_device->isOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QDeviceBuffer::write(QIODevice* device) {
|
void QDeviceBuffer::write(QIODevice *device)
|
||||||
|
{
|
||||||
Q_UNUSED(device)
|
Q_UNUSED(device)
|
||||||
// Not implemented
|
// Not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 QDeviceBuffer::indexOf(const QByteArray& ba, qint64 from) {
|
qint64 QDeviceBuffer::indexOf(const QByteArray& ba, qint64 from)
|
||||||
|
{
|
||||||
const auto MAX = std::numeric_limits<int>::max();
|
const auto MAX = std::numeric_limits<int>::max();
|
||||||
qint64 idx = -1;
|
qint64 idx = -1;
|
||||||
|
|
||||||
if(from < m_device->size()) {
|
if(from < m_device->size())
|
||||||
|
{
|
||||||
idx = from;
|
idx = from;
|
||||||
m_device->seek(from);
|
m_device->seek(from);
|
||||||
|
|
||||||
while(idx < m_device->size()) {
|
while(idx < m_device->size())
|
||||||
|
{
|
||||||
QByteArray data = m_device->read(MAX);
|
QByteArray data = m_device->read(MAX);
|
||||||
int sidx = data.indexOf(ba);
|
int sidx = data.indexOf(ba);
|
||||||
|
|
||||||
if(sidx >= 0) {
|
if(sidx >= 0)
|
||||||
|
{
|
||||||
idx += sidx;
|
idx += sidx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(idx + data.size() >= m_device->size())
|
if(idx + data.size() >= m_device->size()) return -1;
|
||||||
return -1;
|
|
||||||
m_device->seek(m_device->pos() + data.size() - ba.size());
|
m_device->seek(m_device->pos() + data.size() - ba.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,29 +97,33 @@ qint64 QDeviceBuffer::indexOf(const QByteArray& ba, qint64 from) {
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 QDeviceBuffer::lastIndexOf(const QByteArray& ba, qint64 from) {
|
qint64 QDeviceBuffer::lastIndexOf(const QByteArray& ba, qint64 from)
|
||||||
|
{
|
||||||
const auto MAX = std::numeric_limits<int>::max();
|
const auto MAX = std::numeric_limits<int>::max();
|
||||||
qint64 idx = -1;
|
qint64 idx = -1;
|
||||||
|
|
||||||
if(from >= 0 && ba.size() < MAX) {
|
if(from >= 0 && ba.size() < MAX)
|
||||||
|
{
|
||||||
qint64 currpos = from;
|
qint64 currpos = from;
|
||||||
|
|
||||||
while(currpos >= 0) {
|
while(currpos >= 0)
|
||||||
|
{
|
||||||
qint64 readpos = (currpos < MAX) ? 0 : currpos - MAX;
|
qint64 readpos = (currpos < MAX) ? 0 : currpos - MAX;
|
||||||
m_device->seek(readpos);
|
m_device->seek(readpos);
|
||||||
|
|
||||||
QByteArray data = m_device->read(currpos - readpos);
|
QByteArray data = m_device->read(currpos - readpos);
|
||||||
int lidx = data.lastIndexOf(ba, from);
|
int lidx = data.lastIndexOf(ba, from);
|
||||||
|
|
||||||
if(lidx >= 0) {
|
if(lidx >= 0)
|
||||||
|
{
|
||||||
idx = readpos + lidx;
|
idx = readpos + lidx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(readpos <= 0)
|
if(readpos <= 0) break;
|
||||||
break;
|
|
||||||
currpos = readpos + ba.size();
|
currpos = readpos + ba.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return idx;
|
return idx;
|
25
UEFITool/qhexview5/model/buffer/qdevicebuffer.h
Normal file
25
UEFITool/qhexview5/model/buffer/qdevicebuffer.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "qhexbuffer.h"
|
||||||
|
|
||||||
|
class QDeviceBuffer : public QHexBuffer
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit QDeviceBuffer(QObject *parent = nullptr);
|
||||||
|
virtual ~QDeviceBuffer();
|
||||||
|
uchar at(qint64 idx) override;
|
||||||
|
qint64 length() const override;
|
||||||
|
void insert(qint64 offset, const QByteArray& data) override;
|
||||||
|
void replace(qint64 offset, const QByteArray& data) override;
|
||||||
|
void remove(qint64 offset, int length) override;
|
||||||
|
QByteArray read(qint64 offset, int length) override;
|
||||||
|
bool read(QIODevice* device) override;
|
||||||
|
void write(QIODevice* device) override;
|
||||||
|
qint64 indexOf(const QByteArray& ba, qint64 from) override;
|
||||||
|
qint64 lastIndexOf(const QByteArray& ba, qint64 from) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QIODevice* m_device{nullptr};
|
||||||
|
};
|
|
@ -1,21 +1,18 @@
|
||||||
|
#include "qhexbuffer.h"
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QHexView/model/buffer/qhexbuffer.h>
|
|
||||||
|
|
||||||
QHexBuffer::QHexBuffer(QObject* parent): QObject{parent} {}
|
QHexBuffer::QHexBuffer(QObject *parent) : QObject{parent} { }
|
||||||
uchar QHexBuffer::at(qint64 idx) { return this->read(idx, 1).at(0); }
|
uchar QHexBuffer::at(qint64 idx) { return this->read(idx, 1).at(0); }
|
||||||
bool QHexBuffer::isEmpty() const { return this->length() <= 0; }
|
bool QHexBuffer::isEmpty() const { return this->length() <= 0; }
|
||||||
|
|
||||||
void QHexBuffer::replace(qint64 offset, const QByteArray& data) {
|
void QHexBuffer::replace(qint64 offset, const QByteArray &data)
|
||||||
|
{
|
||||||
this->remove(offset, data.length());
|
this->remove(offset, data.length());
|
||||||
this->insert(offset, data);
|
this->insert(offset, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QHexBuffer::accept(qint64 idx) const {
|
void QHexBuffer::read(char *data, int size)
|
||||||
Q_UNUSED(idx);
|
{
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexBuffer::read(char* data, int size) {
|
|
||||||
QBuffer* buffer = new QBuffer(this);
|
QBuffer* buffer = new QBuffer(this);
|
||||||
buffer->setData(data, size);
|
buffer->setData(data, size);
|
||||||
|
|
||||||
|
@ -25,7 +22,8 @@ void QHexBuffer::read(char* data, int size) {
|
||||||
this->read(buffer);
|
this->read(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexBuffer::read(const QByteArray& ba) {
|
void QHexBuffer::read(const QByteArray &ba)
|
||||||
|
{
|
||||||
QBuffer* buffer = new QBuffer(this);
|
QBuffer* buffer = new QBuffer(this);
|
||||||
|
|
||||||
buffer->setData(ba);
|
buffer->setData(ba);
|
||||||
|
@ -34,3 +32,4 @@ void QHexBuffer::read(const QByteArray& ba) {
|
||||||
|
|
||||||
this->read(buffer);
|
this->read(buffer);
|
||||||
}
|
}
|
||||||
|
|
30
UEFITool/qhexview5/model/buffer/qhexbuffer.h
Normal file
30
UEFITool/qhexview5/model/buffer/qhexbuffer.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QIODevice>
|
||||||
|
|
||||||
|
class QHexBuffer : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit QHexBuffer(QObject *parent = nullptr);
|
||||||
|
bool isEmpty() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual uchar at(qint64 idx);
|
||||||
|
virtual void replace(qint64 offset, const QByteArray& data);
|
||||||
|
virtual void read(char* data, int size);
|
||||||
|
virtual void read(const QByteArray& ba);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual qint64 length() const = 0;
|
||||||
|
virtual void insert(qint64 offset, const QByteArray& data) = 0;
|
||||||
|
virtual void remove(qint64 offset, int length) = 0;
|
||||||
|
virtual QByteArray read(qint64 offset, int length) = 0;
|
||||||
|
virtual bool read(QIODevice* iodevice) = 0;
|
||||||
|
virtual void write(QIODevice* iodevice) = 0;
|
||||||
|
virtual qint64 indexOf(const QByteArray& ba, qint64 from) = 0;
|
||||||
|
virtual qint64 lastIndexOf(const QByteArray& ba, qint64 from) = 0;
|
||||||
|
|
||||||
|
};
|
19
UEFITool/qhexview5/model/buffer/qmemorybuffer.cpp
Normal file
19
UEFITool/qhexview5/model/buffer/qmemorybuffer.cpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "qmemorybuffer.h"
|
||||||
|
#include <QIODevice>
|
||||||
|
|
||||||
|
QMemoryBuffer::QMemoryBuffer(QObject *parent) : QHexBuffer{parent} { }
|
||||||
|
uchar QMemoryBuffer::at(qint64 idx) { return static_cast<uchar>(m_buffer.at(idx)); }
|
||||||
|
qint64 QMemoryBuffer::length() const { return static_cast<qint64>(m_buffer.length()); }
|
||||||
|
void QMemoryBuffer::insert(qint64 offset, const QByteArray &data) { m_buffer.insert(static_cast<int>(offset), data); }
|
||||||
|
void QMemoryBuffer::remove(qint64 offset, int length) { m_buffer.remove(static_cast<int>(offset), length); }
|
||||||
|
QByteArray QMemoryBuffer::read(qint64 offset, int length) { return m_buffer.mid(static_cast<int>(offset), length); }
|
||||||
|
|
||||||
|
bool QMemoryBuffer::read(QIODevice *device)
|
||||||
|
{
|
||||||
|
m_buffer = device->readAll();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMemoryBuffer::write(QIODevice *device) { device->write(m_buffer); }
|
||||||
|
qint64 QMemoryBuffer::indexOf(const QByteArray& ba, qint64 from) { return m_buffer.indexOf(ba, static_cast<int>(from)); }
|
||||||
|
qint64 QMemoryBuffer::lastIndexOf(const QByteArray& ba, qint64 from) { return m_buffer.lastIndexOf(ba, static_cast<int>(from)); }
|
23
UEFITool/qhexview5/model/buffer/qmemorybuffer.h
Normal file
23
UEFITool/qhexview5/model/buffer/qmemorybuffer.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "qhexbuffer.h"
|
||||||
|
|
||||||
|
class QMemoryBuffer : public QHexBuffer
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit QMemoryBuffer(QObject *parent = nullptr);
|
||||||
|
uchar at(qint64 idx) override;
|
||||||
|
qint64 length() const override;
|
||||||
|
void insert(qint64 offset, const QByteArray& data) override;
|
||||||
|
void remove(qint64 offset, int length) override;
|
||||||
|
QByteArray read(qint64 offset, int length) override;
|
||||||
|
bool read(QIODevice* device) override;
|
||||||
|
void write(QIODevice* device) override;
|
||||||
|
qint64 indexOf(const QByteArray& ba, qint64 from) override;
|
||||||
|
qint64 lastIndexOf(const QByteArray& ba, qint64 from) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QByteArray m_buffer;
|
||||||
|
};
|
3
UEFITool/qhexview5/model/commands/hexcommand.cpp
Normal file
3
UEFITool/qhexview5/model/commands/hexcommand.cpp
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#include "hexcommand.h"
|
||||||
|
|
||||||
|
HexCommand::HexCommand(QHexBuffer *buffer, QHexDocument* document, QUndoCommand *parent): QUndoCommand(parent), m_hexdocument(document), m_buffer(buffer), m_offset(0), m_length(0) { }
|
19
UEFITool/qhexview5/model/commands/hexcommand.h
Normal file
19
UEFITool/qhexview5/model/commands/hexcommand.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QUndoCommand>
|
||||||
|
#include "../buffer/qhexbuffer.h"
|
||||||
|
|
||||||
|
class QHexDocument;
|
||||||
|
|
||||||
|
class HexCommand: public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HexCommand(QHexBuffer* buffer, QHexDocument* document, QUndoCommand* parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QHexDocument* m_hexdocument;
|
||||||
|
QHexBuffer* m_buffer;
|
||||||
|
qint64 m_offset;
|
||||||
|
int m_length;
|
||||||
|
QByteArray m_data;
|
||||||
|
};
|
16
UEFITool/qhexview5/model/commands/insertcommand.cpp
Normal file
16
UEFITool/qhexview5/model/commands/insertcommand.cpp
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#include "insertcommand.h"
|
||||||
|
#include "../qhexdocument.h"
|
||||||
|
|
||||||
|
InsertCommand::InsertCommand(QHexBuffer *buffer, QHexDocument* document, qint64 offset, const QByteArray &data, QUndoCommand *parent): HexCommand(buffer, document, parent)
|
||||||
|
{
|
||||||
|
m_offset = offset;
|
||||||
|
m_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertCommand::undo()
|
||||||
|
{
|
||||||
|
m_buffer->remove(m_offset, m_data.length());
|
||||||
|
Q_EMIT m_hexdocument->dataChanged(m_data, m_offset, QHexDocument::ChangeReason::Remove);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertCommand::redo() { m_buffer->insert(m_offset, m_data); }
|
11
UEFITool/qhexview5/model/commands/insertcommand.h
Normal file
11
UEFITool/qhexview5/model/commands/insertcommand.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "hexcommand.h"
|
||||||
|
|
||||||
|
class InsertCommand: public HexCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InsertCommand(QHexBuffer* buffer, QHexDocument* document, qint64 offset, const QByteArray& data, QUndoCommand* parent = nullptr);
|
||||||
|
void undo() override;
|
||||||
|
void redo() override;
|
||||||
|
};
|
20
UEFITool/qhexview5/model/commands/removecommand.cpp
Normal file
20
UEFITool/qhexview5/model/commands/removecommand.cpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "removecommand.h"
|
||||||
|
#include "../qhexdocument.h"
|
||||||
|
|
||||||
|
RemoveCommand::RemoveCommand(QHexBuffer *buffer, QHexDocument* document, qint64 offset, int length, QUndoCommand *parent): HexCommand(buffer, document, parent)
|
||||||
|
{
|
||||||
|
m_offset = offset;
|
||||||
|
m_length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveCommand::undo()
|
||||||
|
{
|
||||||
|
m_buffer->insert(m_offset, m_data);
|
||||||
|
Q_EMIT m_hexdocument->dataChanged(m_data, m_offset, QHexDocument::ChangeReason::Insert);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveCommand::redo()
|
||||||
|
{
|
||||||
|
m_data = m_buffer->read(m_offset, m_length); // Backup data
|
||||||
|
m_buffer->remove(m_offset, m_length);
|
||||||
|
}
|
11
UEFITool/qhexview5/model/commands/removecommand.h
Normal file
11
UEFITool/qhexview5/model/commands/removecommand.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "hexcommand.h"
|
||||||
|
|
||||||
|
class RemoveCommand: public HexCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RemoveCommand(QHexBuffer* buffer, QHexDocument* document, qint64 offset, int length, QUndoCommand* parent = nullptr);
|
||||||
|
void undo() override;
|
||||||
|
void redo() override;
|
||||||
|
};
|
20
UEFITool/qhexview5/model/commands/replacecommand.cpp
Normal file
20
UEFITool/qhexview5/model/commands/replacecommand.cpp
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "replacecommand.h"
|
||||||
|
#include "../qhexdocument.h"
|
||||||
|
|
||||||
|
ReplaceCommand::ReplaceCommand(QHexBuffer *buffer, QHexDocument* document, qint64 offset, const QByteArray &data, QUndoCommand *parent): HexCommand(buffer, document, parent)
|
||||||
|
{
|
||||||
|
m_offset = offset;
|
||||||
|
m_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplaceCommand::undo()
|
||||||
|
{
|
||||||
|
m_buffer->replace(m_offset, m_olddata);
|
||||||
|
Q_EMIT m_hexdocument->dataChanged(m_olddata, m_offset, QHexDocument::ChangeReason::Replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReplaceCommand::redo()
|
||||||
|
{
|
||||||
|
m_olddata = m_buffer->read(m_offset, m_data.length());
|
||||||
|
m_buffer->replace(m_offset, m_data);
|
||||||
|
}
|
14
UEFITool/qhexview5/model/commands/replacecommand.h
Normal file
14
UEFITool/qhexview5/model/commands/replacecommand.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "hexcommand.h"
|
||||||
|
|
||||||
|
class ReplaceCommand: public HexCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReplaceCommand(QHexBuffer* buffer, QHexDocument* document, qint64 offset, const QByteArray& data, QUndoCommand* parent = nullptr);
|
||||||
|
void undo() override;
|
||||||
|
void redo() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QByteArray m_olddata;
|
||||||
|
};
|
129
UEFITool/qhexview5/model/qhexcursor.cpp
Normal file
129
UEFITool/qhexview5/model/qhexcursor.cpp
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
#include "../qhexview.h"
|
||||||
|
#include "qhexcursor.h"
|
||||||
|
#include "qhexdocument.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* https://stackoverflow.com/questions/10803043/inverse-column-row-major-order-transformation
|
||||||
|
*
|
||||||
|
* If the index is calculated as:
|
||||||
|
* offset = row + column*NUMROWS
|
||||||
|
* then the inverse would be:
|
||||||
|
* row = offset % NUMROWS
|
||||||
|
* column = offset / NUMROWS
|
||||||
|
* where % is modulus, and / is integer division.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QHexCursor::QHexCursor(const QHexOptions* options, QHexView* parent) : QObject(parent), m_options(options) { }
|
||||||
|
QHexView* QHexCursor::hexView() const { return qobject_cast<QHexView*>(this->parent()); }
|
||||||
|
QHexCursor::Mode QHexCursor::mode() const { return m_mode; }
|
||||||
|
qint64 QHexCursor::offset() const { return this->positionToOffset(m_position); }
|
||||||
|
qint64 QHexCursor::address() const { return m_options->baseaddress + this->offset(); }
|
||||||
|
quint64 QHexCursor::lineAddress() const { return m_options->baseaddress + (m_position.line * m_options->linelength); }
|
||||||
|
qint64 QHexCursor::selectionStartOffset() const { return this->positionToOffset(this->selectionStart()); }
|
||||||
|
qint64 QHexCursor::selectionEndOffset() const { return this->positionToOffset(this->selectionEnd()); }
|
||||||
|
qint64 QHexCursor::line() const { return m_position.line; }
|
||||||
|
qint64 QHexCursor::column() const { return m_position.column; }
|
||||||
|
|
||||||
|
QHexPosition QHexCursor::selectionStart() const
|
||||||
|
{
|
||||||
|
if(m_position.line < m_selection.line)
|
||||||
|
return m_position;
|
||||||
|
|
||||||
|
if(m_position.line == m_selection.line)
|
||||||
|
{
|
||||||
|
if(m_position.column < m_selection.column)
|
||||||
|
return m_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHexPosition QHexCursor::selectionEnd() const
|
||||||
|
{
|
||||||
|
if(m_position.line > m_selection.line)
|
||||||
|
return m_position;
|
||||||
|
|
||||||
|
if(m_position.line == m_selection.line)
|
||||||
|
{
|
||||||
|
if(m_position.column > m_selection.column)
|
||||||
|
return m_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QHexCursor::selectionLength() const
|
||||||
|
{
|
||||||
|
auto selstart = this->selectionStartOffset(), selend = this->selectionEndOffset();
|
||||||
|
return selstart == selend ? 0 : selend - selstart + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHexPosition QHexCursor::position() const { return m_position; }
|
||||||
|
QByteArray QHexCursor::selectedBytes() const { return this->hexView()->selectedBytes(); }
|
||||||
|
bool QHexCursor::hasSelection() const { return m_position != m_selection; }
|
||||||
|
|
||||||
|
bool QHexCursor::isSelected(qint64 line, qint64 column) const
|
||||||
|
{
|
||||||
|
if(!this->hasSelection()) return false;
|
||||||
|
|
||||||
|
auto selstart = this->selectionStart(), selend = this->selectionEnd();
|
||||||
|
if(line > selstart.line && line < selend.line) return true;
|
||||||
|
if(line == selstart.line && line == selend.line) return column >= selstart.column && column <= selend.column;
|
||||||
|
if(line == selstart.line) return column >= selstart.column;
|
||||||
|
if(line == selend.line) return column <= selend.column;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QHexCursor::setMode(Mode m)
|
||||||
|
{
|
||||||
|
if(m_mode == m) return;
|
||||||
|
m_mode = m;
|
||||||
|
Q_EMIT modeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QHexCursor::switchMode()
|
||||||
|
{
|
||||||
|
switch(m_mode)
|
||||||
|
{
|
||||||
|
case Mode::Insert: this->setMode(Mode::Overwrite); break;
|
||||||
|
case Mode::Overwrite: this->setMode(Mode::Insert); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QHexCursor::move(qint64 offset) { this->move(this->offsetToPosition(offset)); }
|
||||||
|
void QHexCursor::move(qint64 line, qint64 column) { return this->move({line, column}); }
|
||||||
|
|
||||||
|
void QHexCursor::move(QHexPosition pos)
|
||||||
|
{
|
||||||
|
if(pos.line >= 0) m_selection.line = pos.line;
|
||||||
|
if(pos.column >= 0) m_selection.column = pos.column;
|
||||||
|
this->select(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QHexCursor::select(qint64 offset) { this->select(this->offsetToPosition(offset)); }
|
||||||
|
void QHexCursor::select(qint64 line, qint64 column) { this->select({line, column}); }
|
||||||
|
|
||||||
|
void QHexCursor::select(QHexPosition pos)
|
||||||
|
{
|
||||||
|
if(pos.line >= 0) m_position.line = pos.line;
|
||||||
|
if(pos.column >= 0) m_position.column = pos.column;
|
||||||
|
Q_EMIT positionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QHexCursor::selectSize(qint64 length)
|
||||||
|
{
|
||||||
|
if(length > 0) length--;
|
||||||
|
else if(length < 0) length++;
|
||||||
|
if(length) this->select(this->offset() + length);
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QHexCursor::replace(const QVariant& oldvalue, const QVariant& newvalue, qint64 offset, QHexFindMode mode, unsigned int options, QHexFindDirection fd) const { return this->hexView()->replace(oldvalue, newvalue, offset, mode, options, fd); }
|
||||||
|
qint64 QHexCursor::find(const QVariant& value, qint64 offset, QHexFindMode mode, unsigned int options, QHexFindDirection fd) const { return this->hexView()->find(value, offset, mode, options, fd); }
|
||||||
|
void QHexCursor::cut(bool hex) { this->hexView()->cut(hex); }
|
||||||
|
void QHexCursor::copy(bool hex) const { this->hexView()->copy(hex); }
|
||||||
|
void QHexCursor::paste(bool hex) { this->hexView()->paste(hex); }
|
||||||
|
void QHexCursor::selectAll() { this->hexView()->selectAll(); }
|
||||||
|
void QHexCursor::removeSelection() { this->hexView()->removeSelection(); }
|
||||||
|
void QHexCursor::clearSelection() { m_position = m_selection; Q_EMIT positionChanged(); }
|
||||||
|
qint64 QHexCursor::positionToOffset(QHexPosition pos) const { return QHexUtils::positionToOffset(m_options, pos); }
|
||||||
|
QHexPosition QHexCursor::offsetToPosition(qint64 offset) const { return QHexUtils::offsetToPosition(m_options, offset); }
|
69
UEFITool/qhexview5/model/qhexcursor.h
Normal file
69
UEFITool/qhexview5/model/qhexcursor.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include "qhexoptions.h"
|
||||||
|
#include "qhexutils.h"
|
||||||
|
|
||||||
|
class QHexView;
|
||||||
|
|
||||||
|
class QHexCursor : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum class Mode { Overwrite, Insert };
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit QHexCursor(const QHexOptions* options, QHexView *parent = nullptr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
QHexView* hexView() const;
|
||||||
|
Mode mode() const;
|
||||||
|
qint64 line() const;
|
||||||
|
qint64 column() const;
|
||||||
|
qint64 offset() const;
|
||||||
|
qint64 address() const;
|
||||||
|
quint64 lineAddress() const;
|
||||||
|
qint64 selectionStartOffset() const;
|
||||||
|
qint64 selectionEndOffset() const;
|
||||||
|
qint64 selectionLength() const;
|
||||||
|
QHexPosition position() const;
|
||||||
|
QHexPosition selectionStart() const;
|
||||||
|
QHexPosition selectionEnd() const;
|
||||||
|
QByteArray selectedBytes() const;
|
||||||
|
bool hasSelection() const;
|
||||||
|
bool isSelected(qint64 line, qint64 column) const;
|
||||||
|
void setMode(Mode m);
|
||||||
|
void move(qint64 offset);
|
||||||
|
void move(qint64 line, qint64 column);
|
||||||
|
void move(QHexPosition pos);
|
||||||
|
void select(qint64 offset);
|
||||||
|
void select(qint64 line, qint64 column);
|
||||||
|
void select(QHexPosition pos);
|
||||||
|
void selectSize(qint64 length);
|
||||||
|
qint64 replace(const QVariant& oldvalue, const QVariant& newvalue, qint64 offset, QHexFindMode mode = QHexFindMode::Text, unsigned int options = QHexFindOptions::None, QHexFindDirection fd = QHexFindDirection::Forward) const;
|
||||||
|
qint64 find(const QVariant& value, qint64 offset, QHexFindMode mode = QHexFindMode::Text, unsigned int options = QHexFindOptions::None, QHexFindDirection fd = QHexFindDirection::Forward) const;
|
||||||
|
qint64 positionToOffset(QHexPosition pos) const;
|
||||||
|
QHexPosition offsetToPosition(qint64 offset) const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void cut(bool hex = false);
|
||||||
|
void copy(bool hex = false) const;
|
||||||
|
void paste(bool hex = false);
|
||||||
|
void selectAll();
|
||||||
|
void removeSelection();
|
||||||
|
void clearSelection();
|
||||||
|
void switchMode();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void positionChanged();
|
||||||
|
void modeChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const QHexOptions* m_options;
|
||||||
|
Mode m_mode{Mode::Overwrite};
|
||||||
|
QHexPosition m_position{}, m_selection{};
|
||||||
|
|
||||||
|
friend class QHexView;
|
||||||
|
};
|
||||||
|
|
|
@ -1,48 +1,50 @@
|
||||||
#include <QHexView/model/qhexdelegate.h>
|
#include "../qhexview.h"
|
||||||
#include <QHexView/qhexview.h>
|
#include "qhexdelegate.h"
|
||||||
|
|
||||||
QHexDelegate::QHexDelegate(QObject* parent): QObject{parent} {}
|
QHexDelegate::QHexDelegate(QObject* parent): QObject{parent} { }
|
||||||
|
|
||||||
QString QHexDelegate::addressHeader(const QHexView* hexview) const {
|
QString QHexDelegate::addressHeader(const QHexView* hexview) const
|
||||||
|
{
|
||||||
Q_UNUSED(hexview);
|
Q_UNUSED(hexview);
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QHexDelegate::hexHeader(const QHexView* hexview) const {
|
QString QHexDelegate::hexHeader(const QHexView* hexview) const
|
||||||
|
{
|
||||||
Q_UNUSED(hexview);
|
Q_UNUSED(hexview);
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QHexDelegate::asciiHeader(const QHexView* hexview) const {
|
QString QHexDelegate::asciiHeader(const QHexView* hexview) const
|
||||||
|
{
|
||||||
Q_UNUSED(hexview);
|
Q_UNUSED(hexview);
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexDelegate::renderAddress(quint64 address, QTextCharFormat& cf,
|
void QHexDelegate::renderAddress(quint64 address, QTextCharFormat& cf, const QHexView* hexview) const
|
||||||
const QHexView* hexview) const {
|
{
|
||||||
Q_UNUSED(address);
|
Q_UNUSED(address);
|
||||||
Q_UNUSED(hexview);
|
Q_UNUSED(hexview);
|
||||||
Q_UNUSED(cf);
|
Q_UNUSED(cf);
|
||||||
Q_UNUSED(hexview);
|
Q_UNUSED(hexview);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexDelegate::renderHeader(QTextBlockFormat& bf,
|
void QHexDelegate::renderHeader(QTextBlockFormat& bf, const QHexView* hexview) const
|
||||||
const QHexView* hexview) const {
|
{
|
||||||
Q_UNUSED(bf);
|
Q_UNUSED(bf);
|
||||||
Q_UNUSED(hexview);
|
Q_UNUSED(hexview);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexDelegate::renderHeaderPart(const QString& s, QHexArea area,
|
void QHexDelegate::renderHeaderPart(const QString& s, QHexArea area, QTextCharFormat& cf, const QHexView* hexview) const
|
||||||
QTextCharFormat& cf,
|
{
|
||||||
const QHexView* hexview) const {
|
|
||||||
Q_UNUSED(s);
|
Q_UNUSED(s);
|
||||||
Q_UNUSED(area);
|
Q_UNUSED(area);
|
||||||
Q_UNUSED(cf);
|
Q_UNUSED(cf);
|
||||||
Q_UNUSED(hexview);
|
Q_UNUSED(hexview);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QHexDelegate::render(quint64 offset, quint8 b, QTextCharFormat& outcf,
|
bool QHexDelegate::render(quint64 offset, quint8 b, QTextCharFormat& outcf, const QHexView* hexview) const
|
||||||
const QHexView* hexview) const {
|
{
|
||||||
Q_UNUSED(offset);
|
Q_UNUSED(offset);
|
||||||
Q_UNUSED(b);
|
Q_UNUSED(b);
|
||||||
Q_UNUSED(outcf);
|
Q_UNUSED(outcf);
|
||||||
|
@ -51,15 +53,16 @@ bool QHexDelegate::render(quint64 offset, quint8 b, QTextCharFormat& outcf,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QHexDelegate::paintSeparator(QPainter* painter, QLineF line,
|
bool QHexDelegate::paintSeparator(QPainter* painter, QLineF line, const QHexView* hexview) const
|
||||||
const QHexView* hexview) const {
|
{
|
||||||
Q_UNUSED(painter);
|
Q_UNUSED(painter);
|
||||||
Q_UNUSED(line);
|
Q_UNUSED(line);
|
||||||
Q_UNUSED(hexview);
|
Q_UNUSED(hexview);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexDelegate::paint(QPainter* painter, const QHexView* hexview) const {
|
void QHexDelegate::paint(QPainter* painter, const QHexView* hexview) const
|
||||||
|
{
|
||||||
Q_UNUSED(hexview);
|
Q_UNUSED(hexview);
|
||||||
hexview->paint(painter);
|
hexview->paint(painter);
|
||||||
}
|
}
|
25
UEFITool/qhexview5/model/qhexdelegate.h
Normal file
25
UEFITool/qhexview5/model/qhexdelegate.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QTextCharFormat>
|
||||||
|
#include <QObject>
|
||||||
|
#include "qhexutils.h"
|
||||||
|
|
||||||
|
class QHexView;
|
||||||
|
|
||||||
|
class QHexDelegate: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit QHexDelegate(QObject* parent = nullptr);
|
||||||
|
virtual ~QHexDelegate() = default;
|
||||||
|
virtual QString addressHeader(const QHexView* hexview) const;
|
||||||
|
virtual QString hexHeader(const QHexView* hexview) const;
|
||||||
|
virtual QString asciiHeader(const QHexView* hexview) const;
|
||||||
|
virtual void renderAddress(quint64 address, QTextCharFormat& cf, const QHexView* hexview) const;
|
||||||
|
virtual void renderHeader(QTextBlockFormat& bf, const QHexView* hexview) const;
|
||||||
|
virtual void renderHeaderPart(const QString& s, QHexArea area, QTextCharFormat& cf, const QHexView* hexview) const;
|
||||||
|
virtual bool render(quint64 offset, quint8 b, QTextCharFormat& outcf, const QHexView* hexview) const;
|
||||||
|
virtual bool paintSeparator(QPainter* painter, QLineF line, const QHexView* hexview) const;
|
||||||
|
virtual void paint(QPainter* painter, const QHexView* hexview) const;
|
||||||
|
};
|
92
UEFITool/qhexview5/model/qhexdocument.cpp
Normal file
92
UEFITool/qhexview5/model/qhexdocument.cpp
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
#include "qhexdocument.h"
|
||||||
|
#include "buffer/qmemorybuffer.h"
|
||||||
|
#include "commands/insertcommand.h"
|
||||||
|
#include "commands/replacecommand.h"
|
||||||
|
#include "commands/removecommand.h"
|
||||||
|
#include "qhexutils.h"
|
||||||
|
#include <QBuffer>
|
||||||
|
#include <QFile>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
QHexDocument::QHexDocument(QHexBuffer *buffer, QObject* parent): QObject(parent)
|
||||||
|
{
|
||||||
|
m_buffer = buffer;
|
||||||
|
m_buffer->setParent(this); // Take Ownership
|
||||||
|
|
||||||
|
connect(&m_undostack, &QUndoStack::canUndoChanged, this, &QHexDocument::canUndoChanged);
|
||||||
|
connect(&m_undostack, &QUndoStack::canRedoChanged, this, &QHexDocument::canRedoChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QHexDocument::indexOf(const QByteArray& ba, qint64 from) { return m_buffer->indexOf(ba, from); }
|
||||||
|
qint64 QHexDocument::lastIndexOf(const QByteArray& ba, qint64 from) { return m_buffer->lastIndexOf(ba, from); }
|
||||||
|
bool QHexDocument::isEmpty() const { return m_buffer->isEmpty(); }
|
||||||
|
bool QHexDocument::canUndo() const { return m_undostack.canUndo(); }
|
||||||
|
bool QHexDocument::canRedo() const { return m_undostack.canRedo(); }
|
||||||
|
|
||||||
|
void QHexDocument::setData(const QByteArray& ba)
|
||||||
|
{
|
||||||
|
QHexBuffer* mb = new QMemoryBuffer();
|
||||||
|
mb->read(ba);
|
||||||
|
this->setData(mb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QHexDocument::setData(QHexBuffer* buffer)
|
||||||
|
{
|
||||||
|
if(!buffer) return;
|
||||||
|
|
||||||
|
m_undostack.clear();
|
||||||
|
buffer->setParent(this);
|
||||||
|
|
||||||
|
auto* oldbuffer = m_buffer;
|
||||||
|
m_buffer = buffer;
|
||||||
|
if(oldbuffer) oldbuffer->deleteLater();
|
||||||
|
|
||||||
|
Q_EMIT canUndoChanged(false);
|
||||||
|
Q_EMIT canRedoChanged(false);
|
||||||
|
Q_EMIT changed();
|
||||||
|
Q_EMIT reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 QHexDocument::length() const { return m_buffer ? m_buffer->length() : 0; }
|
||||||
|
uchar QHexDocument::at(int offset) const { return m_buffer->at(offset); }
|
||||||
|
|
||||||
|
void QHexDocument::undo() { m_undostack.undo(); Q_EMIT changed(); }
|
||||||
|
void QHexDocument::redo() { m_undostack.redo(); Q_EMIT changed(); }
|
||||||
|
void QHexDocument::insert(qint64 offset, uchar b) { this->insert(offset, QByteArray(1, b)); }
|
||||||
|
void QHexDocument::replace(qint64 offset, uchar b) { this->replace(offset, QByteArray(1, b)); }
|
||||||
|
|
||||||
|
void QHexDocument::insert(qint64 offset, const QByteArray &data)
|
||||||
|
{
|
||||||
|
m_undostack.push(new InsertCommand(m_buffer, this, offset, data));
|
||||||
|
|
||||||
|
Q_EMIT changed();
|
||||||
|
Q_EMIT dataChanged(data, offset, ChangeReason::Insert);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QHexDocument::replace(qint64 offset, const QByteArray &data)
|
||||||
|
{
|
||||||
|
m_undostack.push(new ReplaceCommand(m_buffer, this, offset, data));
|
||||||
|
Q_EMIT changed();
|
||||||
|
Q_EMIT dataChanged(data, offset, ChangeReason::Replace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QHexDocument::remove(qint64 offset, int len)
|
||||||
|
{
|
||||||
|
QByteArray data = m_buffer->read(offset, len);
|
||||||
|
|
||||||
|
m_undostack.push(new RemoveCommand(m_buffer, this, offset, len));
|
||||||
|
Q_EMIT changed();
|
||||||
|
Q_EMIT dataChanged(data, offset, ChangeReason::Remove);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray QHexDocument::read(qint64 offset, int len) const { return m_buffer->read(offset, len); }
|
||||||
|
|
||||||
|
bool QHexDocument::saveTo(QIODevice *device)
|
||||||
|
{
|
||||||
|
if(!device->isWritable()) return false;
|
||||||
|
m_buffer->write(device);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHexDocument* QHexDocument::fromBuffer(QHexBuffer* buffer, QObject* parent) { return new QHexDocument(buffer, parent); }
|
||||||
|
QHexDocument* QHexDocument::create(QObject* parent) { return QHexDocument::fromMemory<QMemoryBuffer>({}, parent); }
|
88
UEFITool/qhexview5/model/qhexdocument.h
Normal file
88
UEFITool/qhexview5/model/qhexdocument.h
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QUndoStack>
|
||||||
|
#include "buffer/qhexbuffer.h"
|
||||||
|
#include "qhexmetadata.h"
|
||||||
|
#include "qhexoptions.h"
|
||||||
|
|
||||||
|
class QHexCursor;
|
||||||
|
|
||||||
|
class QHexDocument: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum class ChangeReason { Insert, Remove, Replace };
|
||||||
|
enum class FindDirection { Forward, Backward };
|
||||||
|
Q_ENUM(ChangeReason);
|
||||||
|
Q_ENUM(FindDirection);
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit QHexDocument(QHexBuffer* buffer, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool isEmpty() const;
|
||||||
|
bool canUndo() const;
|
||||||
|
bool canRedo() const;
|
||||||
|
void setData(const QByteArray& ba);
|
||||||
|
void setData(QHexBuffer* buffer);
|
||||||
|
qint64 length() const;
|
||||||
|
qint64 indexOf(const QByteArray& ba, qint64 from = 0);
|
||||||
|
qint64 lastIndexOf(const QByteArray& ba, qint64 from = 0);
|
||||||
|
QByteArray read(qint64 offset, int len = 0) const;
|
||||||
|
uchar at(int offset) const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void undo();
|
||||||
|
void redo();
|
||||||
|
void insert(qint64 offset, uchar b);
|
||||||
|
void replace(qint64 offset, uchar b);
|
||||||
|
void insert(qint64 offset, const QByteArray& data);
|
||||||
|
void replace(qint64 offset, const QByteArray& data);
|
||||||
|
void remove(qint64 offset, int len);
|
||||||
|
bool saveTo(QIODevice* device);
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename T, bool Owned = true> static QHexDocument* fromDevice(QIODevice* iodevice, QObject* parent = nullptr);
|
||||||
|
template<typename T> static QHexDocument* fromMemory(char *data, int size, QObject* parent = nullptr);
|
||||||
|
template<typename T> static QHexDocument* fromMemory(const QByteArray& ba, QObject* parent = nullptr);
|
||||||
|
static QHexDocument* fromBuffer(QHexBuffer* buffer, QObject* parent = nullptr);
|
||||||
|
static QHexDocument* create(QObject* parent = nullptr);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void canUndoChanged(bool canundo);
|
||||||
|
void canRedoChanged(bool canredo);
|
||||||
|
void dataChanged(const QByteArray& data, quint64 offset, QHexDocument::ChangeReason reason);
|
||||||
|
void changed();
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHexBuffer* m_buffer;
|
||||||
|
QUndoStack m_undostack;
|
||||||
|
|
||||||
|
friend class QHexView;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, bool Owned>
|
||||||
|
QHexDocument* QHexDocument::fromDevice(QIODevice* iodevice, QObject *parent)
|
||||||
|
{
|
||||||
|
QHexBuffer* hexbuffer = new T(parent);
|
||||||
|
if(Owned) iodevice->setParent(hexbuffer);
|
||||||
|
return hexbuffer->read(iodevice) ? new QHexDocument(hexbuffer, parent) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
QHexDocument* QHexDocument::fromMemory(char *data, int size, QObject *parent)
|
||||||
|
{
|
||||||
|
QHexBuffer* hexbuffer = new T();
|
||||||
|
hexbuffer->read(data, size);
|
||||||
|
return new QHexDocument(hexbuffer, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
QHexDocument* QHexDocument::fromMemory(const QByteArray& ba, QObject *parent)
|
||||||
|
{
|
||||||
|
QHexBuffer* hexbuffer = new T();
|
||||||
|
hexbuffer->read(ba);
|
||||||
|
return new QHexDocument(hexbuffer, parent);
|
||||||
|
}
|
|
@ -1,44 +1,44 @@
|
||||||
#include <QHexView/model/qhexcursor.h>
|
#include "qhexmetadata.h"
|
||||||
#include <QHexView/model/qhexmetadata.h>
|
#include "qhexcursor.h"
|
||||||
|
|
||||||
QHexMetadata::QHexMetadata(const QHexOptions* options, QObject* parent)
|
QHexMetadata::QHexMetadata(const QHexOptions* options, QObject *parent) : QObject(parent), m_options(options) { }
|
||||||
: QObject(parent), m_options(options) {}
|
|
||||||
|
|
||||||
const QHexMetadataLine* QHexMetadata::find(qint64 line) const {
|
const QHexMetadataLine* QHexMetadata::find(qint64 line) const
|
||||||
|
{
|
||||||
auto it = m_metadata.find(line);
|
auto it = m_metadata.find(line);
|
||||||
return it != m_metadata.end() ? std::addressof(it.value()) : nullptr;
|
return it != m_metadata.end() ? std::addressof(it.value()) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QHexMetadata::getComment(qint64 line, qint64 column) const {
|
QString QHexMetadata::getComment(qint64 line, qint64 column) const
|
||||||
|
{
|
||||||
auto* metadataline = this->find(line);
|
auto* metadataline = this->find(line);
|
||||||
if(!metadataline)
|
if(!metadataline) return QString();
|
||||||
return QString();
|
|
||||||
|
|
||||||
auto offset = QHexUtils::positionToOffset(m_options, {line, column});
|
auto offset = QHexUtils::positionToOffset(m_options, {line, column});
|
||||||
QStringList comments;
|
QStringList comments;
|
||||||
|
|
||||||
for(auto& mi : *metadataline) {
|
for(auto& mi : *metadataline)
|
||||||
if((offset < mi.begin || offset > mi.end) || mi.comment.isEmpty())
|
{
|
||||||
continue;
|
if((offset < mi.begin || offset > mi.end) || mi.comment.isEmpty()) continue;
|
||||||
comments.push_back(mi.comment);
|
comments.push_back(mi.comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
return comments.join("\n");
|
return comments.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexMetadata::removeMetadata(qint64 line) {
|
void QHexMetadata::removeMetadata(qint64 line)
|
||||||
|
{
|
||||||
auto it = m_metadata.find(line);
|
auto it = m_metadata.find(line);
|
||||||
if(it == m_metadata.end())
|
if(it == m_metadata.end()) return;
|
||||||
return;
|
|
||||||
|
|
||||||
m_metadata.erase(it);
|
m_metadata.erase(it);
|
||||||
Q_EMIT changed();
|
Q_EMIT changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexMetadata::removeBackground(qint64 line) {
|
void QHexMetadata::removeBackground(qint64 line)
|
||||||
|
{
|
||||||
this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool {
|
this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool {
|
||||||
if(!mi.background.isValid())
|
if(!mi.background.isValid()) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
if(mi.foreground.isValid() || !mi.comment.isEmpty()) {
|
if(mi.foreground.isValid() || !mi.comment.isEmpty()) {
|
||||||
mi.background = QColor();
|
mi.background = QColor();
|
||||||
|
@ -49,10 +49,10 @@ void QHexMetadata::removeBackground(qint64 line) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexMetadata::removeForeground(qint64 line) {
|
void QHexMetadata::removeForeground(qint64 line)
|
||||||
|
{
|
||||||
this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool {
|
this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool {
|
||||||
if(!mi.foreground.isValid())
|
if(!mi.foreground.isValid()) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
if(mi.background.isValid() || !mi.comment.isEmpty()) {
|
if(mi.background.isValid() || !mi.comment.isEmpty()) {
|
||||||
mi.foreground = QColor();
|
mi.foreground = QColor();
|
||||||
|
@ -63,10 +63,10 @@ void QHexMetadata::removeForeground(qint64 line) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexMetadata::removeComments(qint64 line) {
|
void QHexMetadata::removeComments(qint64 line)
|
||||||
|
{
|
||||||
this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool {
|
this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool {
|
||||||
if(mi.comment.isEmpty())
|
if(mi.comment.isEmpty()) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
if(mi.foreground.isValid() || mi.background.isValid()) {
|
if(mi.foreground.isValid() || mi.background.isValid()) {
|
||||||
mi.comment.clear();
|
mi.comment.clear();
|
||||||
|
@ -77,10 +77,10 @@ void QHexMetadata::removeComments(qint64 line) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexMetadata::unhighlight(qint64 line) {
|
void QHexMetadata::unhighlight(qint64 line)
|
||||||
|
{
|
||||||
this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool {
|
this->clearMetadata(line, [](QHexMetadataItem& mi) -> bool {
|
||||||
if(!mi.foreground.isValid() && !mi.background.isValid())
|
if(!mi.foreground.isValid() && !mi.background.isValid()) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!mi.comment.isEmpty()) {
|
if(!mi.comment.isEmpty()) {
|
||||||
mi.foreground = QColor();
|
mi.foreground = QColor();
|
||||||
|
@ -92,63 +92,54 @@ void QHexMetadata::unhighlight(qint64 line) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexMetadata::clear() {
|
void QHexMetadata::clear() { m_metadata.clear(); Q_EMIT changed(); }
|
||||||
m_metadata.clear();
|
void QHexMetadata::copy(const QHexMetadata* metadata) { m_metadata = metadata->m_metadata; }
|
||||||
Q_EMIT changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QHexMetadata::copy(const QHexMetadata* metadata) {
|
void QHexMetadata::clearMetadata(qint64 line, ClearMetadataCallback&& cb)
|
||||||
m_metadata = metadata->m_metadata;
|
{
|
||||||
}
|
|
||||||
|
|
||||||
void QHexMetadata::clearMetadata(qint64 line, ClearMetadataCallback&& cb) {
|
|
||||||
auto iit = m_metadata.find(line);
|
auto iit = m_metadata.find(line);
|
||||||
if(iit == m_metadata.end())
|
if(iit == m_metadata.end()) return;
|
||||||
return;
|
|
||||||
|
|
||||||
auto oldsize = iit->size();
|
auto oldsize = iit->size();
|
||||||
|
|
||||||
for(auto it = iit->begin(); it != iit->end();) {
|
for(auto it = iit->begin(); it != iit->end(); )
|
||||||
if(cb(*it))
|
{
|
||||||
it = iit->erase(it);
|
if(cb(*it)) it = iit->erase(it);
|
||||||
else
|
else it++;
|
||||||
it++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(iit->empty()) {
|
if(iit->empty())
|
||||||
|
{
|
||||||
this->removeMetadata(line);
|
this->removeMetadata(line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(oldsize != iit->size())
|
if(oldsize != iit->size()) Q_EMIT changed();
|
||||||
Q_EMIT changed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexMetadata::setMetadata(const QHexMetadataItem& mi) {
|
void QHexMetadata::setMetadata(const QHexMetadataItem& mi)
|
||||||
if(!m_options->linelength)
|
{
|
||||||
return;
|
if(!m_options->linelength) return;
|
||||||
|
|
||||||
const qint64 firstline = mi.begin / m_options->linelength;
|
const qint64 firstline = mi.begin / m_options->linelength;
|
||||||
const qint64 lastline = mi.end / m_options->linelength;
|
const qint64 lastline = mi.end / m_options->linelength;
|
||||||
bool notify = false;
|
bool notify = false;
|
||||||
|
|
||||||
for(auto line = firstline; line <= lastline; line++) {
|
for(auto line = firstline; line <= lastline; line++)
|
||||||
|
{
|
||||||
auto start = line == firstline ? mi.begin % m_options->linelength : 0;
|
auto start = line == firstline ? mi.begin % m_options->linelength : 0;
|
||||||
auto length = line == lastline
|
auto length = line == lastline ? (mi.end % m_options->linelength) - start : m_options->linelength;
|
||||||
? (mi.end % m_options->linelength) - start
|
if(length <= 0) continue;
|
||||||
: m_options->linelength;
|
|
||||||
if(length <= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
notify = true;
|
notify = true;
|
||||||
m_metadata[line].push_back(mi);
|
m_metadata[line].push_back(mi);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(notify)
|
if(notify) Q_EMIT changed();
|
||||||
Q_EMIT changed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QHexMetadata::invalidate() {
|
void QHexMetadata::invalidate()
|
||||||
|
{
|
||||||
auto oldmetadata = m_metadata;
|
auto oldmetadata = m_metadata;
|
||||||
m_metadata.clear();
|
m_metadata.clear();
|
||||||
|
|
64
UEFITool/qhexview5/model/qhexmetadata.h
Normal file
64
UEFITool/qhexview5/model/qhexmetadata.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QList>
|
||||||
|
#include <QColor>
|
||||||
|
#include "qhexoptions.h"
|
||||||
|
|
||||||
|
struct QHexMetadataItem
|
||||||
|
{
|
||||||
|
qint64 begin, end;
|
||||||
|
QColor foreground, background;
|
||||||
|
QString comment;
|
||||||
|
};
|
||||||
|
|
||||||
|
using QHexMetadataLine = QList<QHexMetadataItem>;
|
||||||
|
|
||||||
|
class QHexMetadata : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
using ClearMetadataCallback = std::function<bool(QHexMetadataItem&)>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit QHexMetadata(const QHexOptions* options, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const QHexMetadataLine* find(qint64 line) const;
|
||||||
|
QString getComment(qint64 line, qint64 column) const;
|
||||||
|
void removeMetadata(qint64 line);
|
||||||
|
void removeBackground(qint64 line);
|
||||||
|
void removeForeground(qint64 line);
|
||||||
|
void removeComments(qint64 line);
|
||||||
|
void unhighlight(qint64 line);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline void setMetadata(qint64 begin, qint64 end, const QColor &fgcolor, const QColor &bgcolor, const QString &comment) { this->setMetadata({begin, end, fgcolor, bgcolor, comment}); }
|
||||||
|
inline void setForeground(qint64 begin, qint64 end, const QColor &fgcolor) { this->setMetadata(begin, end, fgcolor, QColor(), QString()); }
|
||||||
|
inline void setBackground(qint64 begin, qint64 end, const QColor &bgcolor) { this->setMetadata(begin, end, QColor(), bgcolor, QString()); }
|
||||||
|
inline void setComment(qint64 begin, qint64 end, const QString& comment) { this->setMetadata(begin, end, QColor(), QColor(), comment); };
|
||||||
|
inline void setMetadataSize(qint64 begin, qint64 length, const QColor &fgcolor, const QColor &bgcolor, const QString &comment) { this->setMetadata({begin, begin + length, fgcolor, bgcolor, comment}); }
|
||||||
|
inline void setForegroundSize(qint64 begin, qint64 length, const QColor &fgcolor) { this->setForeground(begin, begin + length, fgcolor); }
|
||||||
|
inline void setBackgroundSize(qint64 begin, qint64 length, const QColor &bgcolor) { this->setBackground(begin, begin + length, bgcolor); }
|
||||||
|
inline void setCommentSize(qint64 begin, qint64 length, const QString& comment) { this->setComment(begin, begin + length, comment); };
|
||||||
|
|
||||||
|
private:
|
||||||
|
void copy(const QHexMetadata* metadata);
|
||||||
|
void clearMetadata(qint64 line, ClearMetadataCallback&& cb);
|
||||||
|
void setMetadata(const QHexMetadataItem& mi);
|
||||||
|
void invalidate();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void changed();
|
||||||
|
void cleared();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHash<qint64, QHexMetadataLine> m_metadata;
|
||||||
|
const QHexOptions* m_options;
|
||||||
|
|
||||||
|
friend class QHexView;
|
||||||
|
};
|
|
@ -1,12 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QChar>
|
|
||||||
#include <QColor>
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QChar>
|
||||||
|
|
||||||
namespace QHexFlags {
|
namespace QHexFlags {
|
||||||
|
enum: unsigned int {
|
||||||
enum : unsigned int {
|
|
||||||
None = (1 << 0),
|
None = (1 << 0),
|
||||||
HSeparator = (1 << 1),
|
HSeparator = (1 << 1),
|
||||||
VSeparator = (1 << 2),
|
VSeparator = (1 << 2),
|
||||||
|
@ -18,19 +17,19 @@ enum : unsigned int {
|
||||||
|
|
||||||
Separators = HSeparator | VSeparator,
|
Separators = HSeparator | VSeparator,
|
||||||
Styled = StyledHeader | StyledAddress,
|
Styled = StyledHeader | StyledAddress,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QHexColor {
|
struct QHexColor
|
||||||
|
{
|
||||||
QColor foreground;
|
QColor foreground;
|
||||||
QColor background;
|
QColor background;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QHexOptions {
|
struct QHexOptions
|
||||||
|
{
|
||||||
// Appearance
|
// Appearance
|
||||||
QChar unprintablechar{'.'};
|
QChar unprintablechar{'.'};
|
||||||
QChar invalidchar{'?'};
|
|
||||||
QString addresslabel{""};
|
QString addresslabel{""};
|
||||||
QString hexlabel;
|
QString hexlabel;
|
||||||
QString asciilabel;
|
QString asciilabel;
|
||||||
|
@ -39,7 +38,7 @@ struct QHexOptions {
|
||||||
unsigned int linelength{0x10};
|
unsigned int linelength{0x10};
|
||||||
unsigned int addresswidth{0};
|
unsigned int addresswidth{0};
|
||||||
unsigned int grouplength{1};
|
unsigned int grouplength{1};
|
||||||
int scrollsteps{1};
|
unsigned int scrollsteps{1};
|
||||||
|
|
||||||
// Colors & Styles
|
// Colors & Styles
|
||||||
QHash<quint8, QHexColor> bytecolors;
|
QHash<quint8, QHexColor> bytecolors;
|
314
UEFITool/qhexview5/model/qhexutils.cpp
Normal file
314
UEFITool/qhexview5/model/qhexutils.cpp
Normal file
|
@ -0,0 +1,314 @@
|
||||||
|
#include "qhexutils.h"
|
||||||
|
#include "qhexoptions.h"
|
||||||
|
#include "../qhexview.h"
|
||||||
|
#include <QGlobalStatic>
|
||||||
|
#include <QDataStream>
|
||||||
|
#include <QtEndian>
|
||||||
|
#include <QList>
|
||||||
|
#include <QHash>
|
||||||
|
#include <limits>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
#define QHEXVIEW_VARIANT_EQ(x, t) ((x).metaType().id() == QMetaType::Q##t)
|
||||||
|
#else
|
||||||
|
#define QHEXVIEW_VARIANT_EQ(x, t) ((x).type() == QVariant::t)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace QHexUtils {
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC_WITH_ARGS(QList<char>, HEXMAP, ({
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
|
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
||||||
|
}));
|
||||||
|
|
||||||
|
namespace PatternUtils {
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC_WITH_ARGS(QString, WILDCARD_BYTE, ("??"))
|
||||||
|
|
||||||
|
bool check(QString& p, qint64& len)
|
||||||
|
{
|
||||||
|
static QHash<QString, QPair<QString, size_t>> processed; // Cache processed patterns
|
||||||
|
|
||||||
|
auto it = processed.find(p);
|
||||||
|
|
||||||
|
if(it != processed.end())
|
||||||
|
{
|
||||||
|
p = it.value().first;
|
||||||
|
len = it.value().second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString op = p; // Store unprocessed pattern
|
||||||
|
p = p.simplified().replace(" ", "");
|
||||||
|
if(p.isEmpty() || (p.size() % 2)) return false;
|
||||||
|
|
||||||
|
int wccount = 0;
|
||||||
|
|
||||||
|
for(auto i = 0; i < p.size() - 2; i += 2)
|
||||||
|
{
|
||||||
|
const auto& hexb = p.mid(i, 2);
|
||||||
|
|
||||||
|
if(hexb == *WILDCARD_BYTE)
|
||||||
|
{
|
||||||
|
wccount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isxdigit(hexb.at(0).toLatin1()) || !isxdigit(hexb.at(1).toLatin1()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wccount >= p.size()) return false;
|
||||||
|
len = p.size() / 2;
|
||||||
|
processed[op] = qMakePair(p, len); // Cache processed pattern
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match(const QByteArray& data, const QString& pattern)
|
||||||
|
{
|
||||||
|
for(qint64 i = 0, idx = 0; (i <= (pattern.size() - 2)); i += 2, idx++)
|
||||||
|
{
|
||||||
|
if(idx >= data.size()) return false;
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
QStringView hexb = QStringView{pattern}.mid(i, 2);
|
||||||
|
#else
|
||||||
|
const QStringRef& hexb = pattern.midRef(i, 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(hexb == *WILDCARD_BYTE) continue;
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
auto b = static_cast<char>(hexb.toUInt(&ok, 16));
|
||||||
|
if(!ok || (b != data.at(idx))) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
unsigned int countBits(quint64 val)
|
||||||
|
{
|
||||||
|
if(val <= std::numeric_limits<quint8>::max()) return QHexFindOptions::Int8;
|
||||||
|
if(val <= std::numeric_limits<quint16>::max()) return QHexFindOptions::Int16;
|
||||||
|
if(val <= std::numeric_limits<quint32>::max()) return QHexFindOptions::Int32;
|
||||||
|
|
||||||
|
return QHexFindOptions::Int64;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Function>
|
||||||
|
qint64 findIter(qint64 startoffset, QHexFindDirection fd, const QHexView* hexview, Function&& f)
|
||||||
|
{
|
||||||
|
QHexDocument* hexdocument = hexview->hexDocument();
|
||||||
|
qint64 offset = -1;
|
||||||
|
|
||||||
|
QHexFindDirection cfd = fd;
|
||||||
|
if(cfd == QHexFindDirection::All) cfd = QHexFindDirection::Forward;
|
||||||
|
|
||||||
|
qint64 i = startoffset;
|
||||||
|
|
||||||
|
while(offset == -1 && (cfd == QHexFindDirection::Backward ? (i >= 0) : (i < hexdocument->length())))
|
||||||
|
{
|
||||||
|
if(!f(i, offset)) break;
|
||||||
|
|
||||||
|
if(cfd == QHexFindDirection::Backward) i--;
|
||||||
|
else i++;
|
||||||
|
|
||||||
|
if(fd == QHexFindDirection::All && i >= hexdocument->length()) i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 findDefault(const QByteArray& value, qint64 startoffset, const QHexView* hexview, unsigned int options, QHexFindDirection fd)
|
||||||
|
{
|
||||||
|
QHexDocument* hexdocument = hexview->hexDocument();
|
||||||
|
if(value.size() > hexdocument->length()) return -1;
|
||||||
|
|
||||||
|
return findIter(startoffset, fd, hexview, [options, value, hexdocument](qint64 idx, qint64& offset) -> bool {
|
||||||
|
for(auto i = 0; i < value.size(); i++) {
|
||||||
|
qint64 curroffset = idx + i;
|
||||||
|
|
||||||
|
if(curroffset >= hexdocument->length()) {
|
||||||
|
offset = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uchar ch1 = hexdocument->at(curroffset);
|
||||||
|
uchar ch2 = value.at(i);
|
||||||
|
|
||||||
|
if(!(options & QHexFindOptions::CaseSensitive)) {
|
||||||
|
ch1 = std::tolower(ch1);
|
||||||
|
ch2 = std::tolower(ch2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ch1 != ch2) break;
|
||||||
|
if(i == value.size() - 1) offset = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 findWildcard(QString pattern, qint64 startoffset, const QHexView* hexview, QHexFindDirection fd, qint64& patternlen)
|
||||||
|
{
|
||||||
|
QHexDocument* hexdocument = hexview->hexDocument();
|
||||||
|
if(!PatternUtils::check(pattern, patternlen) || (patternlen >= hexdocument->length())) return -1;
|
||||||
|
|
||||||
|
return findIter(startoffset, fd, hexview, [hexdocument, pattern, patternlen](qint64 idx, qint64& offset) -> bool {
|
||||||
|
if(PatternUtils::match(hexdocument->read(idx, patternlen), pattern)) offset = idx;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray variantToByteArray(QVariant value, QHexFindMode mode, unsigned int options)
|
||||||
|
{
|
||||||
|
QByteArray v;
|
||||||
|
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case QHexFindMode::Text:
|
||||||
|
if(QHEXVIEW_VARIANT_EQ(value, String)) v = value.toString().toUtf8();
|
||||||
|
else if(QHEXVIEW_VARIANT_EQ(value, ByteArray)) v = value.toByteArray();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QHexFindMode::Hex: {
|
||||||
|
if(QHEXVIEW_VARIANT_EQ(value, String)) {
|
||||||
|
qint64 len = 0;
|
||||||
|
auto s = value.toString();
|
||||||
|
if(!PatternUtils::check(s, len)) return { };
|
||||||
|
|
||||||
|
bool ok = true;
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
for(auto i = 0; ok && i < s.size(); i += 2) v.push_back(static_cast<char>(QStringView{s}.mid(i, 2).toUInt(&ok, 16)));
|
||||||
|
#else
|
||||||
|
for(auto i = 0; ok && i < s.size(); i += 2) v.push_back(static_cast<char>(s.midRef(i, 2).toUInt(&ok, 16)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!ok) return { };
|
||||||
|
}
|
||||||
|
else if(QHEXVIEW_VARIANT_EQ(value, ByteArray)) v = value.toByteArray();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QHexFindMode::Int: {
|
||||||
|
bool ok = false;
|
||||||
|
uint val = value.toUInt(&ok);
|
||||||
|
if(!ok) return QByteArray{ };
|
||||||
|
|
||||||
|
QDataStream ds(&v, QIODevice::WriteOnly);
|
||||||
|
|
||||||
|
if(options & QHexFindOptions::BigEndian) {
|
||||||
|
if(options & QHexFindOptions::Int8) ds << qToBigEndian<quint8>(val);
|
||||||
|
else if(options & QHexFindOptions::Int16) ds << qToBigEndian<quint16>(val);
|
||||||
|
else if(options & QHexFindOptions::Int32) ds << qToBigEndian<quint32>(val);
|
||||||
|
else if(options & QHexFindOptions::Int64) ds << qToBigEndian<quint64>(val);
|
||||||
|
else return variantToByteArray(value, mode, options | countBits(val));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(options & QHexFindOptions::Int8) ds << static_cast<quint8>(val);
|
||||||
|
else if(options & QHexFindOptions::Int16) ds << static_cast<quint16>(val);
|
||||||
|
else if(options & QHexFindOptions::Int32) ds << static_cast<quint32>(val);
|
||||||
|
else if(options & QHexFindOptions::Int64) ds << static_cast<quint64>(val);
|
||||||
|
else return variantToByteArray(value, mode, options | countBits(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QHexFindMode::Float: {
|
||||||
|
bool ok = false;
|
||||||
|
QDataStream ds(&v, QIODevice::WriteOnly);
|
||||||
|
if(options & QHexFindOptions::Float) ds << value.toFloat(&ok);
|
||||||
|
else if(options & QHexFindOptions::Double) ds << value.toDouble(&ok);
|
||||||
|
if(!ok) return { };
|
||||||
|
}
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
QByteArray toHex(const QByteArray& ba, char sep)
|
||||||
|
{
|
||||||
|
QByteArray hex(sep ? (ba.size() * 3 - 1) : (ba.size() * 2), Qt::Uninitialized);
|
||||||
|
|
||||||
|
for(auto i = 0, o = 0; i < ba.size(); i++)
|
||||||
|
{
|
||||||
|
if(sep && i) hex[o++] = static_cast<uchar>(sep);
|
||||||
|
hex[o++] = HEXMAP->at((ba.at(i) & 0xf0) >> 4);
|
||||||
|
hex[o++] = HEXMAP->at(ba.at(i) & 0x0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray toHex(const QByteArray& ba) { return QHexUtils::toHex(ba, '\0'); }
|
||||||
|
qint64 positionToOffset(const QHexOptions* options, QHexPosition pos) { return options->linelength * pos.line + pos.column; }
|
||||||
|
QHexPosition offsetToPosition(const QHexOptions* options, qint64 offset) { return { offset / options->linelength, offset % options->linelength }; }
|
||||||
|
|
||||||
|
QPair<qint64, qint64> find(const QHexView* hexview, QVariant value, qint64 startoffset, QHexFindMode mode, unsigned int options, QHexFindDirection fd)
|
||||||
|
{
|
||||||
|
qint64 offset, size = 0;
|
||||||
|
if(startoffset == -1) startoffset = static_cast<qint64>(hexview->offset());
|
||||||
|
|
||||||
|
if(mode == QHexFindMode::Hex && QHEXVIEW_VARIANT_EQ(value, String))
|
||||||
|
{
|
||||||
|
offset = QHexUtils::findWildcard(value.toString(), startoffset, hexview, fd, size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto ba = variantToByteArray(value, mode, options);
|
||||||
|
|
||||||
|
if(!ba.isEmpty())
|
||||||
|
{
|
||||||
|
offset = QHexUtils::findDefault(ba, startoffset, hexview, options, fd);
|
||||||
|
size = ba.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
offset = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {offset, offset > -1 ? size : 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkPattern(QString pattern)
|
||||||
|
{
|
||||||
|
qint64 len = 0;
|
||||||
|
return PatternUtils::check(pattern, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPair<qint64, qint64> replace(const QHexView* hexview, QVariant oldvalue, QVariant newvalue, qint64 startoffset, QHexFindMode mode, unsigned int options, QHexFindDirection fd)
|
||||||
|
{
|
||||||
|
auto res = QHexUtils::find(hexview, oldvalue, startoffset, mode, options, fd);
|
||||||
|
|
||||||
|
if(res.first != -1 && res.second > 0)
|
||||||
|
{
|
||||||
|
QHexDocument* hexdocument = hexview->hexDocument();
|
||||||
|
auto ba = variantToByteArray(newvalue, mode, options);
|
||||||
|
|
||||||
|
if(!ba.isEmpty())
|
||||||
|
{
|
||||||
|
hexdocument->remove(res.first, res.second);
|
||||||
|
hexdocument->insert(res.first, ba);
|
||||||
|
res.second = ba.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res.first = -1;
|
||||||
|
res.second = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
48
UEFITool/qhexview5/model/qhexutils.h
Normal file
48
UEFITool/qhexview5/model/qhexutils.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QString>
|
||||||
|
#include <QPair>
|
||||||
|
|
||||||
|
struct QHexOptions;
|
||||||
|
class QHexView;
|
||||||
|
|
||||||
|
namespace QHexFindOptions {
|
||||||
|
enum: unsigned int {
|
||||||
|
None = (1 << 0),
|
||||||
|
CaseSensitive = (1 << 1),
|
||||||
|
Int8 = (1 << 2),
|
||||||
|
Int16 = (1 << 3),
|
||||||
|
Int32 = (1 << 4),
|
||||||
|
Int64 = (1 << 5),
|
||||||
|
Float = (1 << 6),
|
||||||
|
Double = (1 << 7),
|
||||||
|
|
||||||
|
BigEndian = (1 << 11),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class QHexFindMode { Text, Hex, Int, Float };
|
||||||
|
enum class QHexFindDirection { All, Forward, Backward };
|
||||||
|
enum class QHexArea { Header, Address, Hex, Ascii, Extra };
|
||||||
|
|
||||||
|
struct QHexPosition {
|
||||||
|
qint64 line; qint64 column;
|
||||||
|
static inline QHexPosition invalid() { return {-1, -1}; }
|
||||||
|
inline bool isValid() const { return line >= 0 && column >= 0; }
|
||||||
|
inline bool operator==(const QHexPosition& rhs) const { return (line == rhs.line) && (column == rhs.column); }
|
||||||
|
inline bool operator!=(const QHexPosition& rhs) const { return (line != rhs.line) || (column != rhs.column); }
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace QHexUtils {
|
||||||
|
|
||||||
|
QByteArray toHex(const QByteArray& ba, char sep);
|
||||||
|
QByteArray toHex(const QByteArray& ba);
|
||||||
|
qint64 positionToOffset(const QHexOptions* options, QHexPosition pos);
|
||||||
|
QPair<qint64, qint64> find(const QHexView* hexview, QVariant value, qint64 startoffset = 0, QHexFindMode mode = QHexFindMode::Text, unsigned int options = QHexFindOptions::None, QHexFindDirection fd = QHexFindDirection::Forward);
|
||||||
|
QPair<qint64, qint64> replace(const QHexView* hexview, QVariant oldvalue, QVariant newvalue, qint64 startoffset = 0, QHexFindMode mode = QHexFindMode::Text, unsigned int options = QHexFindOptions::None, QHexFindDirection fd = QHexFindDirection::Forward);
|
||||||
|
QHexPosition offsetToPosition(const QHexOptions* options, qint64 offset);
|
||||||
|
bool checkPattern(QString pattern);
|
||||||
|
|
||||||
|
}
|
1264
UEFITool/qhexview5/qhexview.cpp
Normal file
1264
UEFITool/qhexview5/qhexview.cpp
Normal file
File diff suppressed because it is too large
Load diff
169
UEFITool/qhexview5/qhexview.h
Normal file
169
UEFITool/qhexview5/qhexview.h
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define QHEXVIEW_VERSION 5.0
|
||||||
|
|
||||||
|
#include <QAbstractScrollArea>
|
||||||
|
#include <QTextCharFormat>
|
||||||
|
#include <QFontMetricsF>
|
||||||
|
#include <QRectF>
|
||||||
|
#include <QList>
|
||||||
|
#include "model/qhexdelegate.h"
|
||||||
|
#include "model/qhexdocument.h"
|
||||||
|
#include "model/qhexcursor.h"
|
||||||
|
|
||||||
|
#if defined(QHEXVIEW_ENABLE_DIALOGS)
|
||||||
|
class HexFindDialog;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class QHexView : public QAbstractScrollArea
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum class CopyMode { Visual, HexArraySquare, HexArrayCurly, HexArrayChar };
|
||||||
|
Q_ENUM(CopyMode);
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit QHexView(QWidget *parent = nullptr);
|
||||||
|
QRectF headerRect() const;
|
||||||
|
QRectF addressRect() const;
|
||||||
|
QRectF hexRect() const;
|
||||||
|
QRectF asciiRect() const;
|
||||||
|
QHexDocument* hexDocument() const;
|
||||||
|
QHexCursor* hexCursor() const;
|
||||||
|
const QHexMetadata* hexMetadata() const;
|
||||||
|
QHexOptions options() const;
|
||||||
|
QColor getReadableColor(QColor c) const;
|
||||||
|
QByteArray selectedBytes() const;
|
||||||
|
QByteArray getLine(qint64 line) const;
|
||||||
|
unsigned int addressWidth() const;
|
||||||
|
unsigned int lineLength() const;
|
||||||
|
bool canUndo() const;
|
||||||
|
bool canRedo() const;
|
||||||
|
quint64 offset() const;
|
||||||
|
quint64 address() const;
|
||||||
|
QHexPosition position() const;
|
||||||
|
QHexPosition selectionStart() const;
|
||||||
|
QHexPosition selectionEnd() const;
|
||||||
|
quint64 selectionStartOffset() const;
|
||||||
|
quint64 selectionEndOffset() const;
|
||||||
|
quint64 baseAddress() const;
|
||||||
|
quint64 lines() const;
|
||||||
|
qint64 replace(const QVariant& oldvalue, const QVariant& newvalue, qint64 offset, QHexFindMode mode = QHexFindMode::Text, unsigned int options = QHexFindOptions::None, QHexFindDirection fd = QHexFindDirection::Forward) const;
|
||||||
|
qint64 find(const QVariant& value, qint64 offset, QHexFindMode mode = QHexFindMode::Text, unsigned int options = QHexFindOptions::None, QHexFindDirection fd = QHexFindDirection::Forward) const;
|
||||||
|
void setOptions(const QHexOptions& options);
|
||||||
|
void setBaseAddress(quint64 baseaddress);
|
||||||
|
void setDelegate(QHexDelegate* rd);
|
||||||
|
void setDocument(QHexDocument* doc);
|
||||||
|
void setData(const QByteArray& ba);
|
||||||
|
void setData(QHexBuffer* buffer);
|
||||||
|
void setCursorMode(QHexCursor::Mode mode);
|
||||||
|
void setByteColor(quint8 b, QHexColor c);
|
||||||
|
void setByteForeground(quint8 b, QColor c);
|
||||||
|
void setByteBackground(quint8 b, QColor c);
|
||||||
|
void setMetadata(qint64 begin, qint64 end, const QColor &fgcolor, const QColor &bgcolor, const QString &comment);
|
||||||
|
void setForeground(qint64 begin, qint64 end, const QColor &fgcolor);
|
||||||
|
void setBackground(qint64 begin, qint64 end, const QColor &bgcolor);
|
||||||
|
void setComment(qint64 begin, qint64 end, const QString& comment);
|
||||||
|
void setMetadataSize(qint64 begin, qint64 length, const QColor &fgcolor, const QColor &bgcolor, const QString &comment);
|
||||||
|
void setForegroundSize(qint64 begin, qint64 length, const QColor &fgcolor);
|
||||||
|
void setBackgroundSize(qint64 begin, qint64 length, const QColor &bgcolor);
|
||||||
|
void setCommentSize(qint64 begin, qint64 length, const QString& comment);
|
||||||
|
void removeMetadata(qint64 line);
|
||||||
|
void removeBackground(qint64 line);
|
||||||
|
void removeForeground(qint64 line);
|
||||||
|
void removeComments(qint64 line);
|
||||||
|
void unhighlight(qint64 line);
|
||||||
|
void clearMetadata();
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
#if defined(QHEXVIEW_ENABLE_DIALOGS)
|
||||||
|
void showFind();
|
||||||
|
void showReplace();
|
||||||
|
#endif
|
||||||
|
void undo();
|
||||||
|
void redo();
|
||||||
|
void cut(bool hex = false);
|
||||||
|
void copyAs(CopyMode mode = CopyMode::Visual) const;
|
||||||
|
void copy(bool hex = false) const;
|
||||||
|
void paste(bool hex = false);
|
||||||
|
void selectAll();
|
||||||
|
void removeSelection();
|
||||||
|
void switchMode();
|
||||||
|
void setAddressWidth(unsigned int w);
|
||||||
|
void setLineLength(unsigned int l);
|
||||||
|
void setGroupLength(unsigned int l);
|
||||||
|
void setScrollSteps(unsigned int l);
|
||||||
|
void setReadOnly(bool r);
|
||||||
|
void setAutoWidth(bool r);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void paint(QPainter* painter) const;
|
||||||
|
void checkOptions();
|
||||||
|
void checkState();
|
||||||
|
void checkAndUpdate(bool calccolumns = false);
|
||||||
|
void calcColumns();
|
||||||
|
void ensureVisible();
|
||||||
|
void drawSeparators(QPainter* p) const;
|
||||||
|
void drawHeader(QTextCursor& c) const;
|
||||||
|
void drawDocument(QTextCursor& c) const;
|
||||||
|
QTextCharFormat drawFormat(QTextCursor& c, quint8 b, const QString& s, QHexArea area, qint64 line, qint64 column, bool applyformat) const;
|
||||||
|
unsigned int calcAddressWidth() const;
|
||||||
|
int visibleLines(bool absolute = false) const;
|
||||||
|
qint64 getLastColumn(qint64 line) const;
|
||||||
|
qint64 lastLine() const;
|
||||||
|
qreal getNCellsWidth(int n) const;
|
||||||
|
qreal hexColumnWidth() const;
|
||||||
|
qreal hexColumnX() const;
|
||||||
|
qreal asciiColumnX() const;
|
||||||
|
qreal endColumnX() const;
|
||||||
|
qreal cellWidth() const;
|
||||||
|
qreal lineHeight() const;
|
||||||
|
QHexPosition positionFromPoint(QPoint pt) const;
|
||||||
|
QPoint absolutePoint(QPoint pt) const;
|
||||||
|
QHexArea areaFromPoint(QPoint pt) const;
|
||||||
|
void moveNext(bool select = false);
|
||||||
|
void movePrevious(bool select = false);
|
||||||
|
bool keyPressMove(QKeyEvent* e);
|
||||||
|
bool keyPressTextInput(QKeyEvent* e);
|
||||||
|
bool keyPressAction(QKeyEvent* e);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool event(QEvent* e) override;
|
||||||
|
void showEvent(QShowEvent* e) override;
|
||||||
|
void paintEvent(QPaintEvent*) override;
|
||||||
|
void resizeEvent(QResizeEvent* e) override;
|
||||||
|
void focusInEvent(QFocusEvent* e) override;
|
||||||
|
void focusOutEvent(QFocusEvent* e) override;
|
||||||
|
void mousePressEvent(QMouseEvent* e) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent* e) override;
|
||||||
|
void wheelEvent(QWheelEvent* e) override;
|
||||||
|
void keyPressEvent(QKeyEvent *e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QString reduced(const QString& s, int maxlen);
|
||||||
|
static bool isColorLight(QColor c);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void dataChanged(const QByteArray& data, quint64 offset, QHexDocument::ChangeReason reason);
|
||||||
|
void positionChanged();
|
||||||
|
void modeChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_readonly{false}, m_writing{false}, m_autowidth{false};
|
||||||
|
QHexArea m_currentarea{QHexArea::Ascii};
|
||||||
|
QList<QRectF> m_hexcolumns;
|
||||||
|
QFontMetricsF m_fontmetrics;
|
||||||
|
QHexOptions m_options;
|
||||||
|
QHexCursor* m_hexcursor{nullptr};
|
||||||
|
QHexDocument* m_hexdocument{nullptr};
|
||||||
|
QHexMetadata* m_hexmetadata{nullptr};
|
||||||
|
QHexDelegate* m_hexdelegate{nullptr};
|
||||||
|
#if defined(QHEXVIEW_ENABLE_DIALOGS)
|
||||||
|
HexFindDialog *m_hexdlgfind{nullptr}, *m_hexdlgreplace{nullptr};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
friend class QHexDelegate;
|
||||||
|
friend class QHexCursor;
|
||||||
|
};
|
||||||
|
|
|
@ -245,11 +245,9 @@ void UEFITool::populateUi(const QModelIndex ¤t)
|
||||||
|| type == Types::SlicData
|
|| type == Types::SlicData
|
||||||
|| type == Types::NvarEntry
|
|| type == Types::NvarEntry
|
||||||
|| type == Types::VssEntry
|
|| type == Types::VssEntry
|
||||||
|| type == Types::SysFEntry
|
|| type == Types::FsysEntry
|
||||||
|| type == Types::EvsaEntry
|
|| type == Types::EvsaEntry
|
||||||
|| type == Types::PhoenixFlashMapEntry
|
|| type == Types::FlashMapEntry
|
||||||
|| type == Types::InsydeFlashDeviceMapEntry
|
|
||||||
|| type == Types::DellDvarEntry
|
|
||||||
|| type == Types::IfwiHeader
|
|| type == Types::IfwiHeader
|
||||||
|| type == Types::IfwiPartition
|
|| type == Types::IfwiPartition
|
||||||
|| type == Types::FptPartition
|
|| type == Types::FptPartition
|
||||||
|
@ -265,12 +263,10 @@ void UEFITool::populateUi(const QModelIndex ¤t)
|
||||||
ui->menuStoreActions->setEnabled(type == Types::VssStore
|
ui->menuStoreActions->setEnabled(type == Types::VssStore
|
||||||
|| type == Types::Vss2Store
|
|| type == Types::Vss2Store
|
||||||
|| type == Types::FdcStore
|
|| type == Types::FdcStore
|
||||||
|| type == Types::SysFStore
|
|| type == Types::FsysStore
|
||||||
|| type == Types::EvsaStore
|
|| type == Types::EvsaStore
|
||||||
|| type == Types::FtwStore
|
|| type == Types::FtwStore
|
||||||
|| type == Types::PhoenixFlashMapStore
|
|| type == Types::FlashMapStore
|
||||||
|| type == Types::InsydeFlashDeviceMapStore
|
|
||||||
|| type == Types::DellDvarStore
|
|
||||||
|| type == Types::NvarGuidStore
|
|| type == Types::NvarGuidStore
|
||||||
|| type == Types::CmdbStore
|
|| type == Types::CmdbStore
|
||||||
|| type == Types::FptStore
|
|| type == Types::FptStore
|
||||||
|
@ -309,6 +305,8 @@ void UEFITool::search()
|
||||||
if (searchDialog->exec() != QDialog::Accepted)
|
if (searchDialog->exec() != QDialog::Accepted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
QModelIndex rootIndex = model->index(0, 0);
|
||||||
|
|
||||||
int index = searchDialog->ui->tabWidget->currentIndex();
|
int index = searchDialog->ui->tabWidget->currentIndex();
|
||||||
if (index == 0) { // Hex pattern
|
if (index == 0) { // Hex pattern
|
||||||
searchDialog->ui->hexEdit->setFocus();
|
searchDialog->ui->hexEdit->setFocus();
|
||||||
|
@ -322,7 +320,7 @@ void UEFITool::search()
|
||||||
mode = SEARCH_MODE_BODY;
|
mode = SEARCH_MODE_BODY;
|
||||||
else
|
else
|
||||||
mode = SEARCH_MODE_ALL;
|
mode = SEARCH_MODE_ALL;
|
||||||
ffsFinder->findHexPattern(pattern, mode);
|
ffsFinder->findHexPattern(rootIndex, pattern, mode);
|
||||||
showFinderMessages();
|
showFinderMessages();
|
||||||
}
|
}
|
||||||
else if (index == 1) { // GUID
|
else if (index == 1) { // GUID
|
||||||
|
@ -338,7 +336,7 @@ void UEFITool::search()
|
||||||
mode = SEARCH_MODE_BODY;
|
mode = SEARCH_MODE_BODY;
|
||||||
else
|
else
|
||||||
mode = SEARCH_MODE_ALL;
|
mode = SEARCH_MODE_ALL;
|
||||||
ffsFinder->findGuidPattern(pattern, mode);
|
ffsFinder->findGuidPattern(rootIndex, pattern, mode);
|
||||||
showFinderMessages();
|
showFinderMessages();
|
||||||
}
|
}
|
||||||
else if (index == 2) { // Text string
|
else if (index == 2) { // Text string
|
||||||
|
@ -353,7 +351,7 @@ void UEFITool::search()
|
||||||
mode = SEARCH_MODE_BODY;
|
mode = SEARCH_MODE_BODY;
|
||||||
else
|
else
|
||||||
mode = SEARCH_MODE_ALL;
|
mode = SEARCH_MODE_ALL;
|
||||||
ffsFinder->findTextPattern(pattern, mode, searchDialog->ui->textUnicodeCheckBox->isChecked(),
|
ffsFinder->findTextPattern(rootIndex, pattern, mode, searchDialog->ui->textUnicodeCheckBox->isChecked(),
|
||||||
(Qt::CaseSensitivity) searchDialog->ui->textCaseSensitiveCheckBox->isChecked());
|
(Qt::CaseSensitivity) searchDialog->ui->textCaseSensitiveCheckBox->isChecked());
|
||||||
showFinderMessages();
|
showFinderMessages();
|
||||||
}
|
}
|
||||||
|
@ -585,7 +583,7 @@ void UEFITool::about()
|
||||||
QMessageBox::about(this,
|
QMessageBox::about(this,
|
||||||
tr("About UEFITool"),
|
tr("About UEFITool"),
|
||||||
tr("<b>UEFITool %1.</b><br><br>"
|
tr("<b>UEFITool %1.</b><br><br>"
|
||||||
"Copyright (c) 2013-2025, Nikolaj (<b>CodeRush</b>) Schlej, Vitaly (<b>vit9696</b>) Cheptsov, <a href=https://github.com/LongSoft/UEFITool/graphs/contributors>et al</a>.<br><br>"
|
"Copyright (c) 2013-2023, Nikolaj Schlej.<br><br>"
|
||||||
"Program icon made by <a href=https://www.behance.net/alzhidkov>Alexander Zhidkov</a>.<br><br>"
|
"Program icon made by <a href=https://www.behance.net/alzhidkov>Alexander Zhidkov</a>.<br><br>"
|
||||||
"GUI uses QHexView made by <a href=https://github.com/Dax89>Antonio Davide</a>.<br>"
|
"GUI uses QHexView made by <a href=https://github.com/Dax89>Antonio Davide</a>.<br>"
|
||||||
"Qt-less engine uses Bstrlib made by <a href=https://github.com/websnarf>Paul Hsieh</a>.<br>"
|
"Qt-less engine uses Bstrlib made by <a href=https://github.com/websnarf>Paul Hsieh</a>.<br>"
|
||||||
|
@ -911,12 +909,10 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
||||||
case Types::VssStore:
|
case Types::VssStore:
|
||||||
case Types::Vss2Store:
|
case Types::Vss2Store:
|
||||||
case Types::FdcStore:
|
case Types::FdcStore:
|
||||||
case Types::SysFStore:
|
case Types::FsysStore:
|
||||||
case Types::EvsaStore:
|
case Types::EvsaStore:
|
||||||
case Types::FtwStore:
|
case Types::FtwStore:
|
||||||
case Types::PhoenixFlashMapStore:
|
case Types::FlashMapStore:
|
||||||
case Types::InsydeFlashDeviceMapStore:
|
|
||||||
case Types::DellDvarStore:
|
|
||||||
case Types::NvarGuidStore:
|
case Types::NvarGuidStore:
|
||||||
case Types::CmdbStore:
|
case Types::CmdbStore:
|
||||||
case Types::FptStore:
|
case Types::FptStore:
|
||||||
|
@ -949,7 +945,7 @@ void UEFITool::readSettings()
|
||||||
// Set monospace font
|
// Set monospace font
|
||||||
QString fontName;
|
QString fontName;
|
||||||
int fontSize;
|
int fontSize;
|
||||||
#if defined Q_OS_MACOS
|
#if defined Q_OS_OSX
|
||||||
fontName = settings.value("mainWindow/fontName", QString("Menlo")).toString();
|
fontName = settings.value("mainWindow/fontName", QString("Menlo")).toString();
|
||||||
fontSize = settings.value("mainWindow/fontSize", 10).toInt();
|
fontSize = settings.value("mainWindow/fontSize", 10).toInt();
|
||||||
#elif defined Q_OS_WIN
|
#elif defined Q_OS_WIN
|
||||||
|
|
|
@ -51,17 +51,6 @@ HEADERS += uefitool.h \
|
||||||
../common/digest/sha2.h \
|
../common/digest/sha2.h \
|
||||||
../common/digest/sm3.h \
|
../common/digest/sm3.h \
|
||||||
../common/generated/ami_nvar.h \
|
../common/generated/ami_nvar.h \
|
||||||
../common/generated/apple_sysf.h \
|
|
||||||
../common/generated/dell_dvar.h \
|
|
||||||
../common/generated/edk2_vss.h \
|
|
||||||
../common/generated/edk2_vss2.h \
|
|
||||||
../common/generated/edk2_ftw.h \
|
|
||||||
../common/generated/insyde_fdc.h \
|
|
||||||
../common/generated/insyde_fdm.h \
|
|
||||||
../common/generated/ms_slic_marker.h \
|
|
||||||
../common/generated/ms_slic_pubkey.h \
|
|
||||||
../common/generated/phoenix_flm.h \
|
|
||||||
../common/generated/phoenix_evsa.h \
|
|
||||||
../common/generated/intel_acbp_v1.h \
|
../common/generated/intel_acbp_v1.h \
|
||||||
../common/generated/intel_acbp_v2.h \
|
../common/generated/intel_acbp_v2.h \
|
||||||
../common/generated/intel_keym_v1.h \
|
../common/generated/intel_keym_v1.h \
|
||||||
|
@ -73,21 +62,20 @@ HEADERS += uefitool.h \
|
||||||
../common/zlib/zlib.h \
|
../common/zlib/zlib.h \
|
||||||
../common/zlib/crc32.h \
|
../common/zlib/crc32.h \
|
||||||
../version.h \
|
../version.h \
|
||||||
QHexView/include/QHexView/model/buffer/qhexbuffer.h \
|
qhexview5/model/buffer/qhexbuffer.h \
|
||||||
QHexView/include/QHexView/model/buffer/qdevicebuffer.h \
|
qhexview5/model/buffer/qdevicebuffer.h \
|
||||||
QHexView/include/QHexView/model/buffer/qmemorybuffer.h \
|
qhexview5/model/buffer/qmemorybuffer.h \
|
||||||
QHexView/include/QHexView/model/buffer/qmappedfilebuffer.h \
|
qhexview5/model/commands/hexcommand.h \
|
||||||
QHexView/include/QHexView/model/commands/hexcommand.h \
|
qhexview5/model/commands/insertcommand.h \
|
||||||
QHexView/include/QHexView/model/commands/insertcommand.h \
|
qhexview5/model/commands/removecommand.h \
|
||||||
QHexView/include/QHexView/model/commands/removecommand.h \
|
qhexview5/model/commands/replacecommand.h \
|
||||||
QHexView/include/QHexView/model/commands/replacecommand.h \
|
qhexview5/model/qhexcursor.h \
|
||||||
QHexView/include/QHexView/model/qhexcursor.h \
|
qhexview5/model/qhexdelegate.h \
|
||||||
QHexView/include/QHexView/model/qhexdelegate.h \
|
qhexview5/model/qhexdocument.h \
|
||||||
QHexView/include/QHexView/model/qhexdocument.h \
|
qhexview5/model/qhexmetadata.h \
|
||||||
QHexView/include/QHexView/model/qhexmetadata.h \
|
qhexview5/model/qhexoptions.h \
|
||||||
QHexView/include/QHexView/model/qhexoptions.h \
|
qhexview5/model/qhexutils.h \
|
||||||
QHexView/include/QHexView/model/qhexutils.h \
|
qhexview5/qhexview.h
|
||||||
QHexView/include/QHexView/qhexview.h
|
|
||||||
|
|
||||||
SOURCES += uefitool_main.cpp \
|
SOURCES += uefitool_main.cpp \
|
||||||
uefitool.cpp \
|
uefitool.cpp \
|
||||||
|
@ -129,17 +117,6 @@ SOURCES += uefitool_main.cpp \
|
||||||
../common/digest/sha512.c \
|
../common/digest/sha512.c \
|
||||||
../common/digest/sm3.c \
|
../common/digest/sm3.c \
|
||||||
../common/generated/ami_nvar.cpp \
|
../common/generated/ami_nvar.cpp \
|
||||||
../common/generated/apple_sysf.cpp \
|
|
||||||
../common/generated/dell_dvar.cpp \
|
|
||||||
../common/generated/edk2_vss.cpp \
|
|
||||||
../common/generated/edk2_vss2.cpp \
|
|
||||||
../common/generated/edk2_ftw.cpp \
|
|
||||||
../common/generated/insyde_fdc.cpp \
|
|
||||||
../common/generated/insyde_fdm.cpp \
|
|
||||||
../common/generated/ms_slic_marker.cpp \
|
|
||||||
../common/generated/ms_slic_pubkey.cpp \
|
|
||||||
../common/generated/phoenix_flm.cpp \
|
|
||||||
../common/generated/phoenix_evsa.cpp \
|
|
||||||
../common/generated/intel_acbp_v1.cpp \
|
../common/generated/intel_acbp_v1.cpp \
|
||||||
../common/generated/intel_acbp_v2.cpp \
|
../common/generated/intel_acbp_v2.cpp \
|
||||||
../common/generated/intel_keym_v1.cpp \
|
../common/generated/intel_keym_v1.cpp \
|
||||||
|
@ -161,22 +138,19 @@ SOURCES += uefitool_main.cpp \
|
||||||
../common/zlib/trees.c \
|
../common/zlib/trees.c \
|
||||||
../common/zlib/uncompr.c \
|
../common/zlib/uncompr.c \
|
||||||
../common/zlib/zutil.c \
|
../common/zlib/zutil.c \
|
||||||
QHexView/src/model/buffer/qhexbuffer.cpp \
|
qhexview5/model/buffer/qhexbuffer.cpp \
|
||||||
QHexView/src/model/buffer/qdevicebuffer.cpp \
|
qhexview5/model/buffer/qdevicebuffer.cpp \
|
||||||
QHexView/src/model/buffer/qmemorybuffer.cpp \
|
qhexview5/model/buffer/qmemorybuffer.cpp \
|
||||||
QHexView/src/model/buffer/qmappedfilebuffer.cpp \
|
qhexview5/model/commands/hexcommand.cpp \
|
||||||
QHexView/src/model/commands/hexcommand.cpp \
|
qhexview5/model/commands/insertcommand.cpp \
|
||||||
QHexView/src/model/commands/insertcommand.cpp \
|
qhexview5/model/commands/removecommand.cpp \
|
||||||
QHexView/src/model/commands/removecommand.cpp \
|
qhexview5/model/commands/replacecommand.cpp \
|
||||||
QHexView/src/model/commands/replacecommand.cpp \
|
qhexview5/model/qhexcursor.cpp \
|
||||||
QHexView/src/model/qhexcursor.cpp \
|
qhexview5/model/qhexdelegate.cpp \
|
||||||
QHexView/src/model/qhexdelegate.cpp \
|
qhexview5/model/qhexdocument.cpp \
|
||||||
QHexView/src/model/qhexdocument.cpp \
|
qhexview5/model/qhexmetadata.cpp \
|
||||||
QHexView/src/model/qhexmetadata.cpp \
|
qhexview5/model/qhexutils.cpp \
|
||||||
QHexView/src/model/qhexutils.cpp \
|
qhexview5/qhexview.cpp
|
||||||
QHexView/src/qhexview.cpp
|
|
||||||
|
|
||||||
INCLUDEPATH += QHexView/include/
|
|
||||||
|
|
||||||
FORMS += uefitool.ui \
|
FORMS += uefitool.ui \
|
||||||
searchdialog.ui \
|
searchdialog.ui \
|
||||||
|
|
|
@ -26,9 +26,7 @@ public:
|
||||||
setOrganizationName("CodeRush");
|
setOrganizationName("CodeRush");
|
||||||
setOrganizationDomain("coderush.me");
|
setOrganizationDomain("coderush.me");
|
||||||
setApplicationName("UEFITool");
|
setApplicationName("UEFITool");
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
|
|
||||||
setDesktopFileName("uefitool");
|
|
||||||
#endif
|
|
||||||
tool = new UEFITool();
|
tool = new UEFITool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
</screenshot>
|
</screenshot>
|
||||||
</screenshots>
|
</screenshots>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="A70" date="2025-03-13" />
|
<release version="A65" date="2023-02-25" />
|
||||||
</releases>
|
</releases>
|
||||||
<url type="homepage">https://github.com/LongSoft/UEFITool</url>
|
<url type="homepage">https://github.com/LongSoft/UEFITool</url>
|
||||||
<developer_name>LongSoft</developer_name>
|
<developer_name>LongSoft</developer_name>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/* 7zTypes.h -- Basic types
|
/* 7zTypes.h -- Basic types
|
||||||
2024-01-24 : Igor Pavlov : Public domain */
|
2022-04-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_7Z_TYPES_H
|
#ifndef __7Z_TYPES_H
|
||||||
#define ZIP7_7Z_TYPES_H
|
#define __7Z_TYPES_H
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
/* #include <windows.h> */
|
/* #include <windows.h> */
|
||||||
|
@ -52,11 +52,6 @@ typedef int SRes;
|
||||||
#define MY_ALIGN(n)
|
#define MY_ALIGN(n)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
/*
|
|
||||||
// C11/C++11:
|
|
||||||
#include <stdalign.h>
|
|
||||||
#define MY_ALIGN(n) alignas(n)
|
|
||||||
*/
|
|
||||||
#define MY_ALIGN(n) __attribute__ ((aligned(n)))
|
#define MY_ALIGN(n) __attribute__ ((aligned(n)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -67,7 +62,7 @@ typedef int SRes;
|
||||||
typedef unsigned WRes;
|
typedef unsigned WRes;
|
||||||
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
|
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
|
||||||
|
|
||||||
// #define MY_HRES_ERROR_INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR)
|
// #define MY_HRES_ERROR__INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR)
|
||||||
|
|
||||||
#else // _WIN32
|
#else // _WIN32
|
||||||
|
|
||||||
|
@ -75,13 +70,13 @@ typedef unsigned WRes;
|
||||||
typedef int WRes;
|
typedef int WRes;
|
||||||
|
|
||||||
// (FACILITY_ERRNO = 0x800) is 7zip's FACILITY constant to represent (errno) errors in HRESULT
|
// (FACILITY_ERRNO = 0x800) is 7zip's FACILITY constant to represent (errno) errors in HRESULT
|
||||||
#define MY_FACILITY_ERRNO 0x800
|
#define MY__FACILITY_ERRNO 0x800
|
||||||
#define MY_FACILITY_WIN32 7
|
#define MY__FACILITY_WIN32 7
|
||||||
#define MY_FACILITY_WRes MY_FACILITY_ERRNO
|
#define MY__FACILITY__WRes MY__FACILITY_ERRNO
|
||||||
|
|
||||||
#define MY_HRESULT_FROM_errno_CONST_ERROR(x) ((HRESULT)( \
|
#define MY_HRESULT_FROM_errno_CONST_ERROR(x) ((HRESULT)( \
|
||||||
( (HRESULT)(x) & 0x0000FFFF) \
|
( (HRESULT)(x) & 0x0000FFFF) \
|
||||||
| (MY_FACILITY_WRes << 16) \
|
| (MY__FACILITY__WRes << 16) \
|
||||||
| (HRESULT)0x80000000 ))
|
| (HRESULT)0x80000000 ))
|
||||||
|
|
||||||
#define MY_SRes_HRESULT_FROM_WRes(x) \
|
#define MY_SRes_HRESULT_FROM_WRes(x) \
|
||||||
|
@ -125,17 +120,17 @@ typedef int WRes;
|
||||||
#define ERROR_INVALID_REPARSE_DATA ((HRESULT)0x80071128L)
|
#define ERROR_INVALID_REPARSE_DATA ((HRESULT)0x80071128L)
|
||||||
#define ERROR_REPARSE_TAG_INVALID ((HRESULT)0x80071129L)
|
#define ERROR_REPARSE_TAG_INVALID ((HRESULT)0x80071129L)
|
||||||
|
|
||||||
// if (MY_FACILITY_WRes != FACILITY_WIN32),
|
// if (MY__FACILITY__WRes != FACILITY_WIN32),
|
||||||
// we use FACILITY_WIN32 for COM errors:
|
// we use FACILITY_WIN32 for COM errors:
|
||||||
#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
|
#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
|
||||||
#define E_INVALIDARG ((HRESULT)0x80070057L)
|
#define E_INVALIDARG ((HRESULT)0x80070057L)
|
||||||
#define MY_E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L)
|
#define MY__E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// we can use FACILITY_ERRNO for some COM errors, that have errno equivalents:
|
// we can use FACILITY_ERRNO for some COM errors, that have errno equivalents:
|
||||||
#define E_OUTOFMEMORY MY_HRESULT_FROM_errno_CONST_ERROR(ENOMEM)
|
#define E_OUTOFMEMORY MY_HRESULT_FROM_errno_CONST_ERROR(ENOMEM)
|
||||||
#define E_INVALIDARG MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL)
|
#define E_INVALIDARG MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL)
|
||||||
#define MY_E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL)
|
#define MY__E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TEXT(quote) quote
|
#define TEXT(quote) quote
|
||||||
|
@ -161,18 +156,18 @@ typedef int WRes;
|
||||||
|
|
||||||
|
|
||||||
#ifndef RINOK
|
#ifndef RINOK
|
||||||
#define RINOK(x) { const int _result_ = (x); if (_result_ != 0) return _result_; }
|
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RINOK_WRes
|
#ifndef RINOK_WRes
|
||||||
#define RINOK_WRes(x) { const WRes _result_ = (x); if (_result_ != 0) return _result_; }
|
#define RINOK_WRes(x) { WRes __result__ = (x); if (__result__ != 0) return __result__; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef unsigned char Byte;
|
typedef unsigned char Byte;
|
||||||
typedef short Int16;
|
typedef short Int16;
|
||||||
typedef unsigned short UInt16;
|
typedef unsigned short UInt16;
|
||||||
|
|
||||||
#ifdef Z7_DECL_Int32_AS_long
|
#ifdef _LZMA_UINT32_IS_ULONG
|
||||||
typedef long Int32;
|
typedef long Int32;
|
||||||
typedef unsigned long UInt32;
|
typedef unsigned long UInt32;
|
||||||
#else
|
#else
|
||||||
|
@ -211,51 +206,37 @@ typedef size_t SIZE_T;
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
|
|
||||||
#define MY_HRES_ERROR_INTERNAL_ERROR ((HRESULT)0x8007054FL)
|
#define MY_HRES_ERROR__INTERNAL_ERROR ((HRESULT)0x8007054FL)
|
||||||
|
|
||||||
|
|
||||||
#ifdef Z7_DECL_Int64_AS_long
|
#ifdef _SZ_NO_INT_64
|
||||||
|
|
||||||
|
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||||||
|
NOTES: Some code will work incorrectly in that case! */
|
||||||
|
|
||||||
typedef long Int64;
|
typedef long Int64;
|
||||||
typedef unsigned long UInt64;
|
typedef unsigned long UInt64;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(__clang__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
typedef __int64 Int64;
|
typedef __int64 Int64;
|
||||||
typedef unsigned __int64 UInt64;
|
typedef unsigned __int64 UInt64;
|
||||||
#else
|
#define UINT64_CONST(n) n
|
||||||
#if defined(__clang__) || defined(__GNUC__)
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef int64_t Int64;
|
|
||||||
typedef uint64_t UInt64;
|
|
||||||
#else
|
#else
|
||||||
typedef long long int Int64;
|
typedef long long int Int64;
|
||||||
typedef unsigned long long int UInt64;
|
typedef unsigned long long int UInt64;
|
||||||
// #define UINT64_CONST(n) n ## ULL
|
#define UINT64_CONST(n) n ## ULL
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UINT64_CONST(n) n
|
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||||
|
typedef UInt32 SizeT;
|
||||||
|
|
||||||
#ifdef Z7_DECL_SizeT_AS_unsigned_int
|
|
||||||
typedef unsigned int SizeT;
|
|
||||||
#else
|
#else
|
||||||
typedef size_t SizeT;
|
typedef size_t SizeT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
#if (defined(_MSC_VER) && _MSC_VER <= 1200)
|
|
||||||
typedef size_t MY_uintptr_t;
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef uintptr_t MY_uintptr_t;
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef int BoolInt;
|
typedef int BoolInt;
|
||||||
/* typedef BoolInt Bool; */
|
/* typedef BoolInt Bool; */
|
||||||
#define True 1
|
#define True 1
|
||||||
|
@ -263,23 +244,23 @@ typedef int BoolInt;
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define Z7_STDCALL __stdcall
|
#define MY_STD_CALL __stdcall
|
||||||
#else
|
#else
|
||||||
#define Z7_STDCALL
|
#define MY_STD_CALL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
#if _MSC_VER >= 1300
|
#if _MSC_VER >= 1300
|
||||||
#define Z7_NO_INLINE __declspec(noinline)
|
#define MY_NO_INLINE __declspec(noinline)
|
||||||
#else
|
#else
|
||||||
#define Z7_NO_INLINE
|
#define MY_NO_INLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define Z7_FORCE_INLINE __forceinline
|
#define MY_FORCE_INLINE __forceinline
|
||||||
|
|
||||||
#define Z7_CDECL __cdecl
|
#define MY_CDECL __cdecl
|
||||||
#define Z7_FASTCALL __fastcall
|
#define MY_FAST_CALL __fastcall
|
||||||
|
|
||||||
#else // _MSC_VER
|
#else // _MSC_VER
|
||||||
|
|
||||||
|
@ -287,25 +268,27 @@ typedef int BoolInt;
|
||||||
|| (defined(__clang__) && (__clang_major__ >= 4)) \
|
|| (defined(__clang__) && (__clang_major__ >= 4)) \
|
||||||
|| defined(__INTEL_COMPILER) \
|
|| defined(__INTEL_COMPILER) \
|
||||||
|| defined(__xlC__)
|
|| defined(__xlC__)
|
||||||
#define Z7_NO_INLINE __attribute__((noinline))
|
#define MY_NO_INLINE __attribute__((noinline))
|
||||||
#define Z7_FORCE_INLINE __attribute__((always_inline)) inline
|
// #define MY_FORCE_INLINE __attribute__((always_inline)) inline
|
||||||
#else
|
#else
|
||||||
#define Z7_NO_INLINE
|
#define MY_NO_INLINE
|
||||||
#define Z7_FORCE_INLINE
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define Z7_CDECL
|
#define MY_FORCE_INLINE
|
||||||
|
|
||||||
|
|
||||||
|
#define MY_CDECL
|
||||||
|
|
||||||
#if defined(_M_IX86) \
|
#if defined(_M_IX86) \
|
||||||
|| defined(__i386__)
|
|| defined(__i386__)
|
||||||
// #define Z7_FASTCALL __attribute__((fastcall))
|
// #define MY_FAST_CALL __attribute__((fastcall))
|
||||||
// #define Z7_FASTCALL __attribute__((cdecl))
|
// #define MY_FAST_CALL __attribute__((cdecl))
|
||||||
#define Z7_FASTCALL
|
#define MY_FAST_CALL
|
||||||
#elif defined(MY_CPU_AMD64)
|
#elif defined(MY_CPU_AMD64)
|
||||||
// #define Z7_FASTCALL __attribute__((ms_abi))
|
// #define MY_FAST_CALL __attribute__((ms_abi))
|
||||||
#define Z7_FASTCALL
|
#define MY_FAST_CALL
|
||||||
#else
|
#else
|
||||||
#define Z7_FASTCALL
|
#define MY_FAST_CALL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
@ -313,49 +296,41 @@ typedef int BoolInt;
|
||||||
|
|
||||||
/* The following interfaces use first parameter as pointer to structure */
|
/* The following interfaces use first parameter as pointer to structure */
|
||||||
|
|
||||||
// #define Z7_C_IFACE_CONST_QUAL
|
typedef struct IByteIn IByteIn;
|
||||||
#define Z7_C_IFACE_CONST_QUAL const
|
struct IByteIn
|
||||||
|
|
||||||
#define Z7_C_IFACE_DECL(a) \
|
|
||||||
struct a ## _; \
|
|
||||||
typedef Z7_C_IFACE_CONST_QUAL struct a ## _ * a ## Ptr; \
|
|
||||||
typedef struct a ## _ a; \
|
|
||||||
struct a ## _
|
|
||||||
|
|
||||||
|
|
||||||
Z7_C_IFACE_DECL (IByteIn)
|
|
||||||
{
|
{
|
||||||
Byte (*Read)(IByteInPtr p); /* reads one byte, returns 0 in case of EOF or error */
|
Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
|
||||||
};
|
};
|
||||||
#define IByteIn_Read(p) (p)->Read(p)
|
#define IByteIn_Read(p) (p)->Read(p)
|
||||||
|
|
||||||
|
|
||||||
Z7_C_IFACE_DECL (IByteOut)
|
typedef struct IByteOut IByteOut;
|
||||||
|
struct IByteOut
|
||||||
{
|
{
|
||||||
void (*Write)(IByteOutPtr p, Byte b);
|
void (*Write)(const IByteOut *p, Byte b);
|
||||||
};
|
};
|
||||||
#define IByteOut_Write(p, b) (p)->Write(p, b)
|
#define IByteOut_Write(p, b) (p)->Write(p, b)
|
||||||
|
|
||||||
|
|
||||||
Z7_C_IFACE_DECL (ISeqInStream)
|
typedef struct ISeqInStream ISeqInStream;
|
||||||
|
struct ISeqInStream
|
||||||
{
|
{
|
||||||
SRes (*Read)(ISeqInStreamPtr p, void *buf, size_t *size);
|
SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
|
||||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||||
(output(*size) < input(*size)) is allowed */
|
(output(*size) < input(*size)) is allowed */
|
||||||
};
|
};
|
||||||
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
||||||
|
|
||||||
/* try to read as much as avail in stream and limited by (*processedSize) */
|
|
||||||
SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize);
|
|
||||||
/* it can return SZ_ERROR_INPUT_EOF */
|
/* it can return SZ_ERROR_INPUT_EOF */
|
||||||
// SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size);
|
SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
|
||||||
// SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType);
|
SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||||||
SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf);
|
SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
|
||||||
|
|
||||||
|
|
||||||
Z7_C_IFACE_DECL (ISeqOutStream)
|
typedef struct ISeqOutStream ISeqOutStream;
|
||||||
|
struct ISeqOutStream
|
||||||
{
|
{
|
||||||
size_t (*Write)(ISeqOutStreamPtr p, const void *buf, size_t size);
|
size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
|
||||||
/* Returns: result - the number of actually written bytes.
|
/* Returns: result - the number of actually written bytes.
|
||||||
(result < size) means error */
|
(result < size) means error */
|
||||||
};
|
};
|
||||||
|
@ -369,26 +344,29 @@ typedef enum
|
||||||
} ESzSeek;
|
} ESzSeek;
|
||||||
|
|
||||||
|
|
||||||
Z7_C_IFACE_DECL (ISeekInStream)
|
typedef struct ISeekInStream ISeekInStream;
|
||||||
|
struct ISeekInStream
|
||||||
{
|
{
|
||||||
SRes (*Read)(ISeekInStreamPtr p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||||
SRes (*Seek)(ISeekInStreamPtr p, Int64 *pos, ESzSeek origin);
|
SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
|
||||||
};
|
};
|
||||||
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
||||||
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
|
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
|
||||||
|
|
||||||
|
|
||||||
Z7_C_IFACE_DECL (ILookInStream)
|
typedef struct ILookInStream ILookInStream;
|
||||||
|
struct ILookInStream
|
||||||
{
|
{
|
||||||
SRes (*Look)(ILookInStreamPtr p, const void **buf, size_t *size);
|
SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
|
||||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||||
(output(*size) > input(*size)) is not allowed
|
(output(*size) > input(*size)) is not allowed
|
||||||
(output(*size) < input(*size)) is allowed */
|
(output(*size) < input(*size)) is allowed */
|
||||||
SRes (*Skip)(ILookInStreamPtr p, size_t offset);
|
SRes (*Skip)(const ILookInStream *p, size_t offset);
|
||||||
/* offset must be <= output(*size) of Look */
|
/* offset must be <= output(*size) of Look */
|
||||||
SRes (*Read)(ILookInStreamPtr p, void *buf, size_t *size);
|
|
||||||
|
SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
|
||||||
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||||
SRes (*Seek)(ILookInStreamPtr p, Int64 *pos, ESzSeek origin);
|
SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
|
#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
|
||||||
|
@ -397,18 +375,19 @@ Z7_C_IFACE_DECL (ILookInStream)
|
||||||
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
|
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
|
||||||
|
|
||||||
|
|
||||||
SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size);
|
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
|
||||||
SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset);
|
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
|
||||||
|
|
||||||
/* reads via ILookInStream::Read */
|
/* reads via ILookInStream::Read */
|
||||||
SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType);
|
SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
||||||
SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size);
|
SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ILookInStream vt;
|
ILookInStream vt;
|
||||||
ISeekInStreamPtr realStream;
|
const ISeekInStream *realStream;
|
||||||
|
|
||||||
size_t pos;
|
size_t pos;
|
||||||
size_t size; /* it's data size */
|
size_t size; /* it's data size */
|
||||||
|
@ -420,13 +399,13 @@ typedef struct
|
||||||
|
|
||||||
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
|
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
|
||||||
|
|
||||||
#define LookToRead2_INIT(p) { (p)->pos = (p)->size = 0; }
|
#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqInStream vt;
|
ISeqInStream vt;
|
||||||
ILookInStreamPtr realStream;
|
const ILookInStream *realStream;
|
||||||
} CSecToLook;
|
} CSecToLook;
|
||||||
|
|
||||||
void SecToLook_CreateVTable(CSecToLook *p);
|
void SecToLook_CreateVTable(CSecToLook *p);
|
||||||
|
@ -436,19 +415,20 @@ void SecToLook_CreateVTable(CSecToLook *p);
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqInStream vt;
|
ISeqInStream vt;
|
||||||
ILookInStreamPtr realStream;
|
const ILookInStream *realStream;
|
||||||
} CSecToRead;
|
} CSecToRead;
|
||||||
|
|
||||||
void SecToRead_CreateVTable(CSecToRead *p);
|
void SecToRead_CreateVTable(CSecToRead *p);
|
||||||
|
|
||||||
|
|
||||||
Z7_C_IFACE_DECL (ICompressProgress)
|
typedef struct ICompressProgress ICompressProgress;
|
||||||
|
|
||||||
|
struct ICompressProgress
|
||||||
{
|
{
|
||||||
SRes (*Progress)(ICompressProgressPtr p, UInt64 inSize, UInt64 outSize);
|
SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
|
||||||
/* Returns: result. (result != SZ_OK) means break.
|
/* Returns: result. (result != SZ_OK) means break.
|
||||||
Value (UInt64)(Int64)-1 for size means unknown value. */
|
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
|
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
|
||||||
|
|
||||||
|
|
||||||
|
@ -486,13 +466,13 @@ struct ISzAlloc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef Z7_container_of
|
#ifndef MY_container_of
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define Z7_container_of(ptr, type, m) container_of(ptr, type, m)
|
#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
|
||||||
#define Z7_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
|
#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
|
||||||
#define Z7_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
|
#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
|
||||||
#define Z7_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
|
#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -501,64 +481,24 @@ struct ISzAlloc
|
||||||
GCC 4.8.1 : classes with non-public variable members"
|
GCC 4.8.1 : classes with non-public variable members"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define Z7_container_of(ptr, type, m) \
|
#define MY_container_of(ptr, type, m) ((type *)(void *)((char *)(void *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
|
||||||
((type *)(void *)((char *)(void *) \
|
|
||||||
(1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m)))
|
|
||||||
|
|
||||||
#define Z7_container_of_CONST(ptr, type, m) \
|
#endif
|
||||||
((const type *)(const void *)((const char *)(const void *) \
|
|
||||||
(1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m)))
|
#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) \
|
#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
|
||||||
((type *)(void *)(const void *)((const char *)(const void *) \
|
|
||||||
(1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m)))
|
|
||||||
*/
|
*/
|
||||||
|
#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
|
||||||
|
|
||||||
#endif
|
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
|
||||||
|
|
||||||
#define Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr))
|
|
||||||
|
|
||||||
// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
|
|
||||||
#define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of(ptr, type, m)
|
|
||||||
// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m)
|
|
||||||
|
|
||||||
#define Z7_CONTAINER_FROM_VTBL_CONST(ptr, type, m) Z7_container_of_CONST(ptr, type, m)
|
|
||||||
|
|
||||||
#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
|
|
||||||
/*
|
/*
|
||||||
#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL(ptr, type, m)
|
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
|
||||||
*/
|
*/
|
||||||
#if defined (__clang__) || defined(__GNUC__)
|
|
||||||
#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \
|
|
||||||
_Pragma("GCC diagnostic push") \
|
|
||||||
_Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
|
|
||||||
#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL \
|
|
||||||
_Pragma("GCC diagnostic pop")
|
|
||||||
#else
|
|
||||||
#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL
|
|
||||||
#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(ptr, type, m, p) \
|
|
||||||
Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \
|
|
||||||
type *p = Z7_CONTAINER_FROM_VTBL(ptr, type, m); \
|
|
||||||
Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL
|
|
||||||
|
|
||||||
#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(type) \
|
|
||||||
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(pp, type, vt, p)
|
|
||||||
|
|
||||||
|
|
||||||
// #define ZIP7_DECLARE_HANDLE(name) typedef void *name;
|
#define MY_memset_0_ARRAY(a) memset((a), 0, sizeof(a))
|
||||||
#define Z7_DECLARE_HANDLE(name) struct name##_dummy{int unused;}; typedef struct name##_dummy *name;
|
|
||||||
|
|
||||||
|
|
||||||
#define Z7_memset_0_ARRAY(a) memset((a), 0, sizeof(a))
|
|
||||||
|
|
||||||
#ifndef Z7_ARRAY_SIZE
|
|
||||||
#define Z7_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
@ -587,11 +527,3 @@ struct ISzAlloc
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
#ifndef Z7_ST
|
|
||||||
#ifdef _7ZIP_ST
|
|
||||||
#define Z7_ST
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#define MY_VER_MAJOR 24
|
#define MY_VER_MAJOR 22
|
||||||
#define MY_VER_MINOR 9
|
#define MY_VER_MINOR 01
|
||||||
#define MY_VER_BUILD 0
|
#define MY_VER_BUILD 0
|
||||||
#define MY_VERSION_NUMBERS "24.09"
|
#define MY_VERSION_NUMBERS "22.01"
|
||||||
#define MY_VERSION MY_VERSION_NUMBERS
|
#define MY_VERSION MY_VERSION_NUMBERS
|
||||||
|
|
||||||
#ifdef MY_CPU_NAME
|
#ifdef MY_CPU_NAME
|
||||||
|
@ -10,12 +10,12 @@
|
||||||
#define MY_VERSION_CPU MY_VERSION
|
#define MY_VERSION_CPU MY_VERSION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MY_DATE "2024-11-29"
|
#define MY_DATE "2022-07-15"
|
||||||
#undef MY_COPYRIGHT
|
#undef MY_COPYRIGHT
|
||||||
#undef MY_VERSION_COPYRIGHT_DATE
|
#undef MY_VERSION_COPYRIGHT_DATE
|
||||||
#define MY_AUTHOR_NAME "Igor Pavlov"
|
#define MY_AUTHOR_NAME "Igor Pavlov"
|
||||||
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
|
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
|
||||||
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2024 Igor Pavlov"
|
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2022 Igor Pavlov"
|
||||||
|
|
||||||
#ifdef USE_COPYRIGHT_CR
|
#ifdef USE_COPYRIGHT_CR
|
||||||
#define MY_COPYRIGHT MY_COPYRIGHT_CR
|
#define MY_COPYRIGHT MY_COPYRIGHT_CR
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
/* 7zWindows.h -- StdAfx
|
|
||||||
2023-04-02 : Igor Pavlov : Public domain */
|
|
||||||
|
|
||||||
#ifndef ZIP7_INC_7Z_WINDOWS_H
|
|
||||||
#define ZIP7_INC_7Z_WINDOWS_H
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
# pragma clang diagnostic push
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 4668) // '_WIN32_WINNT' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
|
|
||||||
|
|
||||||
#if _MSC_VER == 1900
|
|
||||||
// for old kit10 versions
|
|
||||||
// #pragma warning(disable : 4255) // winuser.h(13979): warning C4255: 'GetThreadDpiAwarenessContext':
|
|
||||||
#endif
|
|
||||||
// win10 Windows Kit:
|
|
||||||
#endif // _MSC_VER
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64)
|
|
||||||
// for msvc6 without sdk2003
|
|
||||||
#define RPC_NO_WINDOWS_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
|
||||||
// #if defined(__GNUC__) && !defined(__clang__)
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
#include <Windows.h>
|
|
||||||
#endif
|
|
||||||
// #include <basetsd.h>
|
|
||||||
// #include <wtypes.h>
|
|
||||||
|
|
||||||
// but if precompiled with clang-cl then we need
|
|
||||||
// #include <windows.h>
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
# pragma clang diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64)
|
|
||||||
#ifndef _W64
|
|
||||||
|
|
||||||
typedef long LONG_PTR, *PLONG_PTR;
|
|
||||||
typedef unsigned long ULONG_PTR, *PULONG_PTR;
|
|
||||||
typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
|
|
||||||
|
|
||||||
#define Z7_OLD_WIN_SDK
|
|
||||||
#endif // _W64
|
|
||||||
#endif // _MSC_VER == 1200
|
|
||||||
|
|
||||||
#ifdef Z7_OLD_WIN_SDK
|
|
||||||
|
|
||||||
#ifndef INVALID_FILE_ATTRIBUTES
|
|
||||||
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
|
|
||||||
#endif
|
|
||||||
#ifndef INVALID_SET_FILE_POINTER
|
|
||||||
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
|
|
||||||
#endif
|
|
||||||
#ifndef FILE_SPECIAL_ACCESS
|
|
||||||
#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ShlObj.h:
|
|
||||||
// #define BIF_NEWDIALOGSTYLE 0x0040
|
|
||||||
|
|
||||||
#pragma warning(disable : 4201)
|
|
||||||
// #pragma warning(disable : 4115)
|
|
||||||
|
|
||||||
#undef VARIANT_TRUE
|
|
||||||
#define VARIANT_TRUE ((VARIANT_BOOL)-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // Z7_OLD_WIN_SDK
|
|
||||||
|
|
||||||
#ifdef UNDER_CE
|
|
||||||
#undef VARIANT_TRUE
|
|
||||||
#define VARIANT_TRUE ((VARIANT_BOOL)-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#if _MSC_VER >= 1400 && _MSC_VER <= 1600
|
|
||||||
// BaseTsd.h(148) : 'HandleToULong' : unreferenced inline function has been removed
|
|
||||||
// string.h
|
|
||||||
// #pragma warning(disable : 4514)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* #include "7zTypes.h" */
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,709 +1,230 @@
|
||||||
/* Bra.c -- Branch converters for RISC code
|
/* Bra.c -- Converters for RISC code
|
||||||
2024-01-20 : Igor Pavlov : Public domain */
|
2021-02-09 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include "Bra.h"
|
|
||||||
#include "RotateDefs.h"
|
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
#include "Bra.h"
|
||||||
|
|
||||||
#if defined(MY_CPU_SIZEOF_POINTER) \
|
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
&& ( MY_CPU_SIZEOF_POINTER == 4 \
|
|
||||||
|| MY_CPU_SIZEOF_POINTER == 8)
|
|
||||||
#define BR_CONV_USE_OPT_PC_PTR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BR_CONV_USE_OPT_PC_PTR
|
|
||||||
#define BR_PC_INIT pc -= (UInt32)(SizeT)p;
|
|
||||||
#define BR_PC_GET (pc + (UInt32)(SizeT)p)
|
|
||||||
#else
|
|
||||||
#define BR_PC_INIT pc += (UInt32)size;
|
|
||||||
#define BR_PC_GET (pc - (UInt32)(SizeT)(lim - p))
|
|
||||||
// #define BR_PC_INIT
|
|
||||||
// #define BR_PC_GET (pc + (UInt32)(SizeT)(p - data))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BR_CONVERT_VAL(v, c) if (encoding) v += c; else v -= c;
|
|
||||||
// #define BR_CONVERT_VAL(v, c) if (!encoding) c = (UInt32)0 - c; v += c;
|
|
||||||
|
|
||||||
#define Z7_BRANCH_CONV(name) z7_ ## name
|
|
||||||
|
|
||||||
#define Z7_BRANCH_FUNC_MAIN(name) \
|
|
||||||
static \
|
|
||||||
Z7_FORCE_INLINE \
|
|
||||||
Z7_ATTRIB_NO_VECTOR \
|
|
||||||
Byte *Z7_BRANCH_CONV(name)(Byte *p, SizeT size, UInt32 pc, int encoding)
|
|
||||||
|
|
||||||
#define Z7_BRANCH_FUNC_IMP(name, m, encoding) \
|
|
||||||
Z7_NO_INLINE \
|
|
||||||
Z7_ATTRIB_NO_VECTOR \
|
|
||||||
Byte *m(name)(Byte *data, SizeT size, UInt32 pc) \
|
|
||||||
{ return Z7_BRANCH_CONV(name)(data, size, pc, encoding); } \
|
|
||||||
|
|
||||||
#ifdef Z7_EXTRACT_ONLY
|
|
||||||
#define Z7_BRANCH_FUNCS_IMP(name) \
|
|
||||||
Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_DEC_2, 0)
|
|
||||||
#else
|
|
||||||
#define Z7_BRANCH_FUNCS_IMP(name) \
|
|
||||||
Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_DEC_2, 0) \
|
|
||||||
Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_ENC_2, 1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
#define BR_EXTERNAL_FOR
|
|
||||||
#define BR_NEXT_ITERATION continue;
|
|
||||||
#else
|
|
||||||
#define BR_EXTERNAL_FOR for (;;)
|
|
||||||
#define BR_NEXT_ITERATION break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__clang__) && (__clang_major__ >= 8) \
|
|
||||||
|| defined(__GNUC__) && (__GNUC__ >= 1000) \
|
|
||||||
// GCC is not good for __builtin_expect() here
|
|
||||||
/* || defined(_MSC_VER) && (_MSC_VER >= 1920) */
|
|
||||||
// #define Z7_unlikely [[unlikely]]
|
|
||||||
// #define Z7_LIKELY(x) (__builtin_expect((x), 1))
|
|
||||||
#define Z7_UNLIKELY(x) (__builtin_expect((x), 0))
|
|
||||||
// #define Z7_likely [[likely]]
|
|
||||||
#else
|
|
||||||
// #define Z7_LIKELY(x) (x)
|
|
||||||
#define Z7_UNLIKELY(x) (x)
|
|
||||||
// #define Z7_likely
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Z7_BRANCH_FUNC_MAIN(BranchConv_ARM64)
|
|
||||||
{
|
{
|
||||||
// Byte *p = data;
|
Byte *p;
|
||||||
const Byte *lim;
|
const Byte *lim;
|
||||||
const UInt32 flag = (UInt32)1 << (24 - 4);
|
size &= ~(size_t)3;
|
||||||
const UInt32 mask = ((UInt32)1 << 24) - (flag << 1);
|
ip += 4;
|
||||||
size &= ~(SizeT)3;
|
p = data;
|
||||||
// if (size == 0) return p;
|
lim = data + size;
|
||||||
lim = p + size;
|
|
||||||
BR_PC_INIT
|
if (encoding)
|
||||||
pc -= 4; // because (p) will point to next instruction
|
|
||||||
|
|
||||||
BR_EXTERNAL_FOR
|
|
||||||
{
|
|
||||||
// Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
UInt32 v;
|
for (;;)
|
||||||
if Z7_UNLIKELY(p == lim)
|
{
|
||||||
return p;
|
if (p >= lim)
|
||||||
v = GetUi32a(p);
|
return (SizeT)(p - data);
|
||||||
p += 4;
|
p += 4;
|
||||||
if Z7_UNLIKELY(((v - 0x94000000) & 0xfc000000) == 0)
|
if (p[-1] == 0xEB)
|
||||||
{
|
|
||||||
UInt32 c = BR_PC_GET >> 2;
|
|
||||||
BR_CONVERT_VAL(v, c)
|
|
||||||
v &= 0x03ffffff;
|
|
||||||
v |= 0x94000000;
|
|
||||||
SetUi32a(p - 4, v)
|
|
||||||
BR_NEXT_ITERATION
|
|
||||||
}
|
|
||||||
// v = rotlFixed(v, 8); v += (flag << 8) - 0x90; if Z7_UNLIKELY((v & ((mask << 8) + 0x9f)) == 0)
|
|
||||||
v -= 0x90000000; if Z7_UNLIKELY((v & 0x9f000000) == 0)
|
|
||||||
{
|
|
||||||
UInt32 z, c;
|
|
||||||
// v = rotrFixed(v, 8);
|
|
||||||
v += flag; if Z7_UNLIKELY(v & mask) continue;
|
|
||||||
z = (v & 0xffffffe0) | (v >> 26);
|
|
||||||
c = (BR_PC_GET >> (12 - 3)) & ~(UInt32)7;
|
|
||||||
BR_CONVERT_VAL(z, c)
|
|
||||||
v &= 0x1f;
|
|
||||||
v |= 0x90000000;
|
|
||||||
v |= z << 26;
|
|
||||||
v |= 0x00ffffe0 & ((z & (((flag << 1) - 1))) - flag);
|
|
||||||
SetUi32a(p - 4, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Z7_BRANCH_FUNCS_IMP(BranchConv_ARM64)
|
|
||||||
|
|
||||||
|
|
||||||
Z7_BRANCH_FUNC_MAIN(BranchConv_ARM)
|
|
||||||
{
|
|
||||||
// Byte *p = data;
|
|
||||||
const Byte *lim;
|
|
||||||
size &= ~(SizeT)3;
|
|
||||||
lim = p + size;
|
|
||||||
BR_PC_INIT
|
|
||||||
/* in ARM: branch offset is relative to the +2 instructions from current instruction.
|
|
||||||
(p) will point to next instruction */
|
|
||||||
pc += 8 - 4;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if Z7_UNLIKELY(p >= lim) { return p; } p += 4; if Z7_UNLIKELY(p[-1] == 0xeb) break;
|
|
||||||
if Z7_UNLIKELY(p >= lim) { return p; } p += 4; if Z7_UNLIKELY(p[-1] == 0xeb) break;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
UInt32 v = GetUi32a(p - 4);
|
|
||||||
UInt32 c = BR_PC_GET >> 2;
|
|
||||||
BR_CONVERT_VAL(v, c)
|
|
||||||
v &= 0x00ffffff;
|
|
||||||
v |= 0xeb000000;
|
|
||||||
SetUi32a(p - 4, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Z7_BRANCH_FUNCS_IMP(BranchConv_ARM)
|
|
||||||
|
|
||||||
|
|
||||||
Z7_BRANCH_FUNC_MAIN(BranchConv_PPC)
|
|
||||||
{
|
|
||||||
// Byte *p = data;
|
|
||||||
const Byte *lim;
|
|
||||||
size &= ~(SizeT)3;
|
|
||||||
lim = p + size;
|
|
||||||
BR_PC_INIT
|
|
||||||
pc -= 4; // because (p) will point to next instruction
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
UInt32 v;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if Z7_UNLIKELY(p == lim)
|
|
||||||
return p;
|
|
||||||
// v = GetBe32a(p);
|
|
||||||
v = *(UInt32 *)(void *)p;
|
|
||||||
p += 4;
|
|
||||||
// if ((v & 0xfc000003) == 0x48000001) break;
|
|
||||||
// if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) break;
|
|
||||||
if Z7_UNLIKELY(
|
|
||||||
((v - Z7_CONV_BE_TO_NATIVE_CONST32(0x48000001))
|
|
||||||
& Z7_CONV_BE_TO_NATIVE_CONST32(0xfc000003)) == 0) break;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
v = Z7_CONV_NATIVE_TO_BE_32(v);
|
|
||||||
{
|
|
||||||
UInt32 c = BR_PC_GET;
|
|
||||||
BR_CONVERT_VAL(v, c)
|
|
||||||
}
|
|
||||||
v &= 0x03ffffff;
|
|
||||||
v |= 0x48000000;
|
|
||||||
SetBe32a(p - 4, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Z7_BRANCH_FUNCS_IMP(BranchConv_PPC)
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef Z7_CPU_FAST_ROTATE_SUPPORTED
|
|
||||||
#define BR_SPARC_USE_ROTATE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Z7_BRANCH_FUNC_MAIN(BranchConv_SPARC)
|
|
||||||
{
|
|
||||||
// Byte *p = data;
|
|
||||||
const Byte *lim;
|
|
||||||
const UInt32 flag = (UInt32)1 << 22;
|
|
||||||
size &= ~(SizeT)3;
|
|
||||||
lim = p + size;
|
|
||||||
BR_PC_INIT
|
|
||||||
pc -= 4; // because (p) will point to next instruction
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
UInt32 v;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if Z7_UNLIKELY(p == lim)
|
|
||||||
return p;
|
|
||||||
/* // the code without GetBe32a():
|
|
||||||
{ const UInt32 v = GetUi16a(p) & 0xc0ff; p += 4; if (v == 0x40 || v == 0xc07f) break; }
|
|
||||||
*/
|
|
||||||
v = GetBe32a(p);
|
|
||||||
p += 4;
|
|
||||||
#ifdef BR_SPARC_USE_ROTATE
|
|
||||||
v = rotlFixed(v, 2);
|
|
||||||
v += (flag << 2) - 1;
|
|
||||||
if Z7_UNLIKELY((v & (3 - (flag << 3))) == 0)
|
|
||||||
#else
|
|
||||||
v += (UInt32)5 << 29;
|
|
||||||
v ^= (UInt32)7 << 29;
|
|
||||||
v += flag;
|
|
||||||
if Z7_UNLIKELY((v & (0 - (flag << 1))) == 0)
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// UInt32 v = GetBe32a(p - 4);
|
UInt32 v = GetUi32(p - 4);
|
||||||
#ifndef BR_SPARC_USE_ROTATE
|
|
||||||
v <<= 2;
|
v <<= 2;
|
||||||
#endif
|
v += ip + (UInt32)(p - data);
|
||||||
{
|
|
||||||
UInt32 c = BR_PC_GET;
|
|
||||||
BR_CONVERT_VAL(v, c)
|
|
||||||
}
|
|
||||||
v &= (flag << 3) - 1;
|
|
||||||
#ifdef BR_SPARC_USE_ROTATE
|
|
||||||
v -= (flag << 2) - 1;
|
|
||||||
v = rotrFixed(v, 2);
|
|
||||||
#else
|
|
||||||
v -= (flag << 2);
|
|
||||||
v >>= 2;
|
v >>= 2;
|
||||||
v |= (UInt32)1 << 30;
|
v &= 0x00FFFFFF;
|
||||||
#endif
|
v |= 0xEB000000;
|
||||||
SetBe32a(p - 4, v)
|
SetUi32(p - 4, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (p >= lim)
|
||||||
|
return (SizeT)(p - data);
|
||||||
|
p += 4;
|
||||||
|
if (p[-1] == 0xEB)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
UInt32 v = GetUi32(p - 4);
|
||||||
|
v <<= 2;
|
||||||
|
v -= ip + (UInt32)(p - data);
|
||||||
|
v >>= 2;
|
||||||
|
v &= 0x00FFFFFF;
|
||||||
|
v |= 0xEB000000;
|
||||||
|
SetUi32(p - 4, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Z7_BRANCH_FUNCS_IMP(BranchConv_SPARC)
|
|
||||||
|
|
||||||
|
|
||||||
Z7_BRANCH_FUNC_MAIN(BranchConv_ARMT)
|
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
{
|
{
|
||||||
// Byte *p = data;
|
Byte *p;
|
||||||
Byte *lim;
|
const Byte *lim;
|
||||||
size &= ~(SizeT)1;
|
size &= ~(size_t)1;
|
||||||
// if (size == 0) return p;
|
p = data;
|
||||||
if (size <= 2) return p;
|
lim = data + size - 4;
|
||||||
size -= 2;
|
|
||||||
lim = p + size;
|
if (encoding)
|
||||||
BR_PC_INIT
|
|
||||||
/* in ARM: branch offset is relative to the +2 instructions from current instruction.
|
|
||||||
(p) will point to the +2 instructions from current instruction */
|
|
||||||
// pc += 4 - 4;
|
|
||||||
// if (encoding) pc -= 0xf800 << 1; else pc += 0xf800 << 1;
|
|
||||||
// #define ARMT_TAIL_PROC { goto armt_tail; }
|
|
||||||
#define ARMT_TAIL_PROC { return p; }
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* in MSVC 32-bit x86 compilers:
|
|
||||||
UInt32 version : it loads value from memory with movzx
|
|
||||||
Byte version : it loads value to 8-bit register (AL/CL)
|
|
||||||
movzx version is slightly faster in some cpus
|
|
||||||
*/
|
|
||||||
unsigned b1;
|
|
||||||
// Byte / unsigned
|
|
||||||
b1 = p[1];
|
|
||||||
// optimized version to reduce one (p >= lim) check:
|
|
||||||
// unsigned a1 = p[1]; b1 = p[3]; p += 2; if Z7_LIKELY((b1 & (a1 ^ 8)) < 0xf8)
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
unsigned b3; // Byte / UInt32
|
UInt32 b1;
|
||||||
/* (Byte)(b3) normalization can use low byte computations in MSVC.
|
for (;;)
|
||||||
It gives smaller code, and no loss of speed in some compilers/cpus.
|
{
|
||||||
But new MSVC 32-bit x86 compilers use more slow load
|
UInt32 b3;
|
||||||
from memory to low byte register in that case.
|
if (p > lim)
|
||||||
So we try to use full 32-bit computations for faster code.
|
return (SizeT)(p - data);
|
||||||
*/
|
b1 = p[1];
|
||||||
// if (p >= lim) { ARMT_TAIL_PROC } b3 = b1 + 8; b1 = p[3]; p += 2; if ((b3 & b1) >= 0xf8) break;
|
b3 = p[3];
|
||||||
if Z7_UNLIKELY(p >= lim) { ARMT_TAIL_PROC } b3 = p[3]; p += 2; if Z7_UNLIKELY((b3 & (b1 ^ 8)) >= 0xf8) break;
|
p += 2;
|
||||||
if Z7_UNLIKELY(p >= lim) { ARMT_TAIL_PROC } b1 = p[3]; p += 2; if Z7_UNLIKELY((b1 & (b3 ^ 8)) >= 0xf8) break;
|
b1 ^= 8;
|
||||||
|
if ((b3 & b1) >= 0xF8)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
/* we can adjust pc for (0xf800) to rid of (& 0x7FF) operation.
|
|
||||||
But gcc/clang for arm64 can use bfi instruction for full code here */
|
|
||||||
UInt32 v =
|
UInt32 v =
|
||||||
((UInt32)GetUi16a(p - 2) << 11) |
|
((UInt32)b1 << 19)
|
||||||
((UInt32)GetUi16a(p) & 0x7FF);
|
|
||||||
/*
|
|
||||||
UInt32 v =
|
|
||||||
((UInt32)p[1 - 2] << 19)
|
|
||||||
+ (((UInt32)p[1] & 0x7) << 8)
|
+ (((UInt32)p[1] & 0x7) << 8)
|
||||||
+ (((UInt32)p[-2] << 11))
|
+ (((UInt32)p[-2] << 11))
|
||||||
+ (p[0]);
|
+ (p[0]);
|
||||||
*/
|
|
||||||
p += 2;
|
p += 2;
|
||||||
{
|
{
|
||||||
UInt32 c = BR_PC_GET >> 1;
|
UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
|
||||||
BR_CONVERT_VAL(v, c)
|
v += cur;
|
||||||
}
|
}
|
||||||
SetUi16a(p - 4, (UInt16)(((v >> 11) & 0x7ff) | 0xf000))
|
|
||||||
SetUi16a(p - 2, (UInt16)(v | 0xf800))
|
|
||||||
/*
|
|
||||||
p[-4] = (Byte)(v >> 11);
|
p[-4] = (Byte)(v >> 11);
|
||||||
p[-3] = (Byte)(0xf0 | ((v >> 19) & 0x7));
|
p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
|
||||||
p[-2] = (Byte)v;
|
p[-2] = (Byte)v;
|
||||||
p[-1] = (Byte)(0xf8 | (v >> 8));
|
p[-1] = (Byte)(0xF8 | (v >> 8));
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (p < lim);
|
|
||||||
return p;
|
|
||||||
// armt_tail:
|
|
||||||
// if ((Byte)((lim[1] & 0xf8)) != 0xf0) { lim += 2; } return lim;
|
|
||||||
// return (Byte *)(lim + ((Byte)((lim[1] ^ 0xf0) & 0xf8) == 0 ? 0 : 2));
|
|
||||||
// return (Byte *)(lim + (((lim[1] ^ ~0xfu) & ~7u) == 0 ? 0 : 2));
|
|
||||||
// return (Byte *)(lim + 2 - (((((unsigned)lim[1] ^ 8) + 8) >> 7) & 2));
|
|
||||||
}
|
|
||||||
Z7_BRANCH_FUNCS_IMP(BranchConv_ARMT)
|
|
||||||
|
|
||||||
|
|
||||||
// #define BR_IA64_NO_INLINE
|
|
||||||
|
|
||||||
Z7_BRANCH_FUNC_MAIN(BranchConv_IA64)
|
|
||||||
{
|
|
||||||
// Byte *p = data;
|
|
||||||
const Byte *lim;
|
|
||||||
size &= ~(SizeT)15;
|
|
||||||
lim = p + size;
|
|
||||||
pc -= 1 << 4;
|
|
||||||
pc >>= 4 - 1;
|
|
||||||
// pc -= 1 << 1;
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
unsigned m;
|
UInt32 b1;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if Z7_UNLIKELY(p == lim)
|
UInt32 b3;
|
||||||
return p;
|
if (p > lim)
|
||||||
m = (unsigned)((UInt32)0x334b0000 >> (*p & 0x1e));
|
return (SizeT)(p - data);
|
||||||
p += 16;
|
b1 = p[1];
|
||||||
pc += 1 << 1;
|
b3 = p[3];
|
||||||
if (m &= 3)
|
p += 2;
|
||||||
|
b1 ^= 8;
|
||||||
|
if ((b3 & b1) >= 0xF8)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
p += (ptrdiff_t)m * 5 - 20; // negative value is expected here.
|
UInt32 v =
|
||||||
do
|
((UInt32)b1 << 19)
|
||||||
|
+ (((UInt32)p[1] & 0x7) << 8)
|
||||||
|
+ (((UInt32)p[-2] << 11))
|
||||||
|
+ (p[0]);
|
||||||
|
|
||||||
|
p += 2;
|
||||||
{
|
{
|
||||||
const UInt32 t =
|
UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
|
||||||
#if defined(MY_CPU_X86_OR_AMD64)
|
v -= cur;
|
||||||
// we use 32-bit load here to reduce code size on x86:
|
|
||||||
GetUi32(p);
|
|
||||||
#else
|
|
||||||
GetUi16(p);
|
|
||||||
#endif
|
|
||||||
UInt32 z = GetUi32(p + 1) >> m;
|
|
||||||
p += 5;
|
|
||||||
if (((t >> m) & (0x70 << 1)) == 0
|
|
||||||
&& ((z - (0x5000000 << 1)) & (0xf000000 << 1)) == 0)
|
|
||||||
{
|
|
||||||
UInt32 v = (UInt32)((0x8fffff << 1) | 1) & z;
|
|
||||||
z ^= v;
|
|
||||||
#ifdef BR_IA64_NO_INLINE
|
|
||||||
v |= (v & ((UInt32)1 << (23 + 1))) >> 3;
|
|
||||||
{
|
|
||||||
UInt32 c = pc;
|
|
||||||
BR_CONVERT_VAL(v, c)
|
|
||||||
}
|
}
|
||||||
v &= (0x1fffff << 1) | 1;
|
|
||||||
#else
|
/*
|
||||||
|
SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
|
||||||
|
SetUi16(p - 2, (UInt16)(v | 0xF800));
|
||||||
|
*/
|
||||||
|
|
||||||
|
p[-4] = (Byte)(v >> 11);
|
||||||
|
p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
|
||||||
|
p[-2] = (Byte)v;
|
||||||
|
p[-1] = (Byte)(0xF8 | (v >> 8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
|
{
|
||||||
|
Byte *p;
|
||||||
|
const Byte *lim;
|
||||||
|
size &= ~(size_t)3;
|
||||||
|
ip -= 4;
|
||||||
|
p = data;
|
||||||
|
lim = data + size;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (p >= lim)
|
||||||
|
return (SizeT)(p - data);
|
||||||
|
p += 4;
|
||||||
|
/* if ((v & 0xFC000003) == 0x48000001) */
|
||||||
|
if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
UInt32 v = GetBe32(p - 4);
|
||||||
if (encoding)
|
if (encoding)
|
||||||
{
|
v += ip + (UInt32)(p - data);
|
||||||
// pc &= ~(0xc00000 << 1); // we just need to clear at least 2 bits
|
|
||||||
pc &= (0x1fffff << 1) | 1;
|
|
||||||
v += pc;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
v -= ip + (UInt32)(p - data);
|
||||||
// pc |= 0xc00000 << 1; // we need to set at least 2 bits
|
v &= 0x03FFFFFF;
|
||||||
pc |= ~(UInt32)((0x1fffff << 1) | 1);
|
v |= 0x48000000;
|
||||||
v -= pc;
|
SetBe32(p - 4, v);
|
||||||
}
|
|
||||||
}
|
|
||||||
v &= ~(UInt32)(0x600000 << 1);
|
|
||||||
#endif
|
|
||||||
v += (0x700000 << 1);
|
|
||||||
v &= (0x8fffff << 1) | 1;
|
|
||||||
z |= v;
|
|
||||||
z <<= m;
|
|
||||||
SetUi32(p + 1 - 5, z)
|
|
||||||
}
|
|
||||||
m++;
|
|
||||||
}
|
|
||||||
while (m &= 3); // while (m < 4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Z7_BRANCH_FUNCS_IMP(BranchConv_IA64)
|
|
||||||
|
|
||||||
|
|
||||||
#define BR_CONVERT_VAL_ENC(v) v += BR_PC_GET;
|
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
#define BR_CONVERT_VAL_DEC(v) v -= BR_PC_GET;
|
|
||||||
|
|
||||||
#if 1 && defined(MY_CPU_LE_UNALIGN)
|
|
||||||
#define RISCV_USE_UNALIGNED_LOAD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef RISCV_USE_UNALIGNED_LOAD
|
|
||||||
#define RISCV_GET_UI32(p) GetUi32(p)
|
|
||||||
#define RISCV_SET_UI32(p, v) { SetUi32(p, v) }
|
|
||||||
#else
|
|
||||||
#define RISCV_GET_UI32(p) \
|
|
||||||
((UInt32)GetUi16a(p) + \
|
|
||||||
((UInt32)GetUi16a((p) + 2) << 16))
|
|
||||||
#define RISCV_SET_UI32(p, v) { \
|
|
||||||
SetUi16a(p, (UInt16)(v)) \
|
|
||||||
SetUi16a((p) + 2, (UInt16)(v >> 16)) }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 1 && defined(MY_CPU_LE)
|
|
||||||
#define RISCV_USE_16BIT_LOAD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef RISCV_USE_16BIT_LOAD
|
|
||||||
#define RISCV_LOAD_VAL(p) GetUi16a(p)
|
|
||||||
#else
|
|
||||||
#define RISCV_LOAD_VAL(p) (*(p))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RISCV_INSTR_SIZE 2
|
|
||||||
#define RISCV_STEP_1 (4 + RISCV_INSTR_SIZE)
|
|
||||||
#define RISCV_STEP_2 4
|
|
||||||
#define RISCV_REG_VAL (2 << 7)
|
|
||||||
#define RISCV_CMD_VAL 3
|
|
||||||
#if 1
|
|
||||||
// for code size optimization:
|
|
||||||
#define RISCV_DELTA_7F 0x7f
|
|
||||||
#else
|
|
||||||
#define RISCV_DELTA_7F 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RISCV_CHECK_1(v, b) \
|
|
||||||
(((((b) - RISCV_CMD_VAL) ^ ((v) << 8)) & (0xf8000 + RISCV_CMD_VAL)) == 0)
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
#define RISCV_CHECK_2(v, r) \
|
|
||||||
((((v) - ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL | 8)) \
|
|
||||||
<< 18) \
|
|
||||||
< ((r) & 0x1d))
|
|
||||||
#else
|
|
||||||
// this branch gives larger code, because
|
|
||||||
// compilers generate larger code for big constants.
|
|
||||||
#define RISCV_CHECK_2(v, r) \
|
|
||||||
((((v) - ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL)) \
|
|
||||||
& ((RISCV_CMD_VAL << 12) | RISCV_REG_VAL)) \
|
|
||||||
< ((r) & 0x1d))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define RISCV_SCAN_LOOP \
|
|
||||||
Byte *lim; \
|
|
||||||
size &= ~(SizeT)(RISCV_INSTR_SIZE - 1); \
|
|
||||||
if (size <= 6) return p; \
|
|
||||||
size -= 6; \
|
|
||||||
lim = p + size; \
|
|
||||||
BR_PC_INIT \
|
|
||||||
for (;;) \
|
|
||||||
{ \
|
|
||||||
UInt32 a, v; \
|
|
||||||
/* Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE */ \
|
|
||||||
for (;;) \
|
|
||||||
{ \
|
|
||||||
if Z7_UNLIKELY(p >= lim) { return p; } \
|
|
||||||
a = (RISCV_LOAD_VAL(p) ^ 0x10u) + 1; \
|
|
||||||
if ((a & 0x77) == 0) break; \
|
|
||||||
a = (RISCV_LOAD_VAL(p + RISCV_INSTR_SIZE) ^ 0x10u) + 1; \
|
|
||||||
p += RISCV_INSTR_SIZE * 2; \
|
|
||||||
if ((a & 0x77) == 0) \
|
|
||||||
{ \
|
|
||||||
p -= RISCV_INSTR_SIZE; \
|
|
||||||
if Z7_UNLIKELY(p >= lim) { return p; } \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
// (xx6f ^ 10) + 1 = xx7f + 1 = xx80 : JAL
|
|
||||||
// (xxef ^ 10) + 1 = xxff + 1 = xx00 + 100 : JAL
|
|
||||||
// (xx17 ^ 10) + 1 = xx07 + 1 = xx08 : AUIPC
|
|
||||||
// (xx97 ^ 10) + 1 = xx87 + 1 = xx88 : AUIPC
|
|
||||||
|
|
||||||
Byte * Z7_BRANCH_CONV_ENC(RISCV)(Byte *p, SizeT size, UInt32 pc)
|
|
||||||
{
|
{
|
||||||
RISCV_SCAN_LOOP
|
Byte *p;
|
||||||
v = a;
|
const Byte *lim;
|
||||||
a = RISCV_GET_UI32(p);
|
size &= ~(size_t)3;
|
||||||
#ifndef RISCV_USE_16BIT_LOAD
|
ip -= 4;
|
||||||
v += (UInt32)p[1] << 8;
|
p = data;
|
||||||
#endif
|
lim = data + size;
|
||||||
|
|
||||||
if ((v & 8) == 0) // JAL
|
for (;;)
|
||||||
{
|
{
|
||||||
if ((v - (0x100 /* - RISCV_DELTA_7F */)) & 0xd80)
|
for (;;)
|
||||||
{
|
{
|
||||||
p += RISCV_INSTR_SIZE;
|
if (p >= lim)
|
||||||
continue;
|
return (SizeT)(p - data);
|
||||||
}
|
/*
|
||||||
{
|
v = GetBe32(p);
|
||||||
v = ((a & 1u << 31) >> 11)
|
|
||||||
| ((a & 0x3ff << 21) >> 20)
|
|
||||||
| ((a & 1 << 20) >> 9)
|
|
||||||
| (a & 0xff << 12);
|
|
||||||
BR_CONVERT_VAL_ENC(v)
|
|
||||||
// ((v & 1) == 0)
|
|
||||||
// v: bits [1 : 20] contain offset bits
|
|
||||||
#if 0 && defined(RISCV_USE_UNALIGNED_LOAD)
|
|
||||||
a &= 0xfff;
|
|
||||||
a |= ((UInt32)(v << 23))
|
|
||||||
| ((UInt32)(v << 7) & ((UInt32)0xff << 16))
|
|
||||||
| ((UInt32)(v >> 5) & ((UInt32)0xf0 << 8));
|
|
||||||
RISCV_SET_UI32(p, a)
|
|
||||||
#else // aligned
|
|
||||||
#if 0
|
|
||||||
SetUi16a(p, (UInt16)(((v >> 5) & 0xf000) | (a & 0xfff)))
|
|
||||||
#else
|
|
||||||
p[1] = (Byte)(((v >> 13) & 0xf0) | ((a >> 8) & 0xf));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE)
|
|
||||||
v <<= 15;
|
|
||||||
v = Z7_BSWAP32(v);
|
|
||||||
SetUi16a(p + 2, (UInt16)v)
|
|
||||||
#else
|
|
||||||
p[2] = (Byte)(v >> 9);
|
|
||||||
p[3] = (Byte)(v >> 1);
|
|
||||||
#endif
|
|
||||||
#endif // aligned
|
|
||||||
}
|
|
||||||
p += 4;
|
p += 4;
|
||||||
continue;
|
m = v + ((UInt32)5 << 29);
|
||||||
} // JAL
|
m ^= (UInt32)7 << 29;
|
||||||
|
m += (UInt32)1 << 22;
|
||||||
{
|
if ((m & ((UInt32)0x1FF << 23)) == 0)
|
||||||
// AUIPC
|
break;
|
||||||
if (v & 0xe80) // (not x0) and (not x2)
|
*/
|
||||||
{
|
|
||||||
const UInt32 b = RISCV_GET_UI32(p + 4);
|
|
||||||
if (RISCV_CHECK_1(v, b))
|
|
||||||
{
|
|
||||||
{
|
|
||||||
const UInt32 temp = (b << 12) | (0x17 + RISCV_REG_VAL);
|
|
||||||
RISCV_SET_UI32(p, temp)
|
|
||||||
}
|
|
||||||
a &= 0xfffff000;
|
|
||||||
{
|
|
||||||
#if 1
|
|
||||||
const int t = -1 >> 1;
|
|
||||||
if (t != -1)
|
|
||||||
a += (b >> 20) - ((b >> 19) & 0x1000); // arithmetic right shift emulation
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
a += (UInt32)((Int32)b >> 20); // arithmetic right shift (sign-extension).
|
|
||||||
}
|
|
||||||
BR_CONVERT_VAL_ENC(a)
|
|
||||||
#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE)
|
|
||||||
a = Z7_BSWAP32(a);
|
|
||||||
RISCV_SET_UI32(p + 4, a)
|
|
||||||
#else
|
|
||||||
SetBe32(p + 4, a)
|
|
||||||
#endif
|
|
||||||
p += 8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
p += RISCV_STEP_1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UInt32 r = a >> 27;
|
|
||||||
if (RISCV_CHECK_2(v, r))
|
|
||||||
{
|
|
||||||
v = RISCV_GET_UI32(p + 4);
|
|
||||||
r = (r << 7) + 0x17 + (v & 0xfffff000);
|
|
||||||
a = (a >> 12) | (v << 20);
|
|
||||||
RISCV_SET_UI32(p, r)
|
|
||||||
RISCV_SET_UI32(p + 4, a)
|
|
||||||
p += 8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
p += RISCV_STEP_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // for
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Byte * Z7_BRANCH_CONV_DEC(RISCV)(Byte *p, SizeT size, UInt32 pc)
|
|
||||||
{
|
|
||||||
RISCV_SCAN_LOOP
|
|
||||||
#ifdef RISCV_USE_16BIT_LOAD
|
|
||||||
if ((a & 8) == 0)
|
|
||||||
{
|
|
||||||
#else
|
|
||||||
v = a;
|
|
||||||
a += (UInt32)p[1] << 8;
|
|
||||||
if ((v & 8) == 0)
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
// JAL
|
|
||||||
a -= 0x100 - RISCV_DELTA_7F;
|
|
||||||
if (a & 0xd80)
|
|
||||||
{
|
|
||||||
p += RISCV_INSTR_SIZE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const UInt32 a_old = (a + (0xef - RISCV_DELTA_7F)) & 0xfff;
|
|
||||||
#if 0 // unaligned
|
|
||||||
a = GetUi32(p);
|
|
||||||
v = (UInt32)(a >> 23) & ((UInt32)0xff << 1)
|
|
||||||
| (UInt32)(a >> 7) & ((UInt32)0xff << 9)
|
|
||||||
#elif 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE)
|
|
||||||
v = GetUi16a(p + 2);
|
|
||||||
v = Z7_BSWAP32(v) >> 15
|
|
||||||
#else
|
|
||||||
v = (UInt32)p[3] << 1
|
|
||||||
| (UInt32)p[2] << 9
|
|
||||||
#endif
|
|
||||||
| (UInt32)((a & 0xf000) << 5);
|
|
||||||
BR_CONVERT_VAL_DEC(v)
|
|
||||||
a = a_old
|
|
||||||
| (v << 11 & 1u << 31)
|
|
||||||
| (v << 20 & 0x3ff << 21)
|
|
||||||
| (v << 9 & 1 << 20)
|
|
||||||
| (v & 0xff << 12);
|
|
||||||
RISCV_SET_UI32(p, a)
|
|
||||||
}
|
|
||||||
p += 4;
|
p += 4;
|
||||||
continue;
|
if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
|
||||||
} // JAL
|
(p[-4] == 0x7F && (p[-3] >= 0xC0)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
UInt32 v = GetBe32(p - 4);
|
||||||
|
v <<= 2;
|
||||||
|
if (encoding)
|
||||||
|
v += ip + (UInt32)(p - data);
|
||||||
|
else
|
||||||
|
v -= ip + (UInt32)(p - data);
|
||||||
|
|
||||||
{
|
v &= 0x01FFFFFF;
|
||||||
// AUIPC
|
v -= (UInt32)1 << 24;
|
||||||
v = a;
|
v ^= 0xFF000000;
|
||||||
#if 1 && defined(RISCV_USE_UNALIGNED_LOAD)
|
v >>= 2;
|
||||||
a = GetUi32(p);
|
v |= 0x40000000;
|
||||||
#else
|
SetBe32(p - 4, v);
|
||||||
a |= (UInt32)GetUi16a(p + 2) << 16;
|
|
||||||
#endif
|
|
||||||
if ((v & 0xe80) == 0) // x0/x2
|
|
||||||
{
|
|
||||||
const UInt32 r = a >> 27;
|
|
||||||
if (RISCV_CHECK_2(v, r))
|
|
||||||
{
|
|
||||||
UInt32 b;
|
|
||||||
#if 1 && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) && defined(MY_CPU_LE)
|
|
||||||
b = RISCV_GET_UI32(p + 4);
|
|
||||||
b = Z7_BSWAP32(b);
|
|
||||||
#else
|
|
||||||
b = GetBe32(p + 4);
|
|
||||||
#endif
|
|
||||||
v = a >> 12;
|
|
||||||
BR_CONVERT_VAL_DEC(b)
|
|
||||||
a = (r << 7) + 0x17;
|
|
||||||
a += (b + 0x800) & 0xfffff000;
|
|
||||||
v |= b << 20;
|
|
||||||
RISCV_SET_UI32(p, a)
|
|
||||||
RISCV_SET_UI32(p + 4, v)
|
|
||||||
p += 8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
p += RISCV_STEP_2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const UInt32 b = RISCV_GET_UI32(p + 4);
|
|
||||||
if (!RISCV_CHECK_1(v, b))
|
|
||||||
p += RISCV_STEP_1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
v = (a & 0xfffff000) | (b >> 20);
|
|
||||||
a = (b << 12) | (0x17 + RISCV_REG_VAL);
|
|
||||||
RISCV_SET_UI32(p, a)
|
|
||||||
RISCV_SET_UI32(p + 4, v)
|
|
||||||
p += 8;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} // for
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,105 +1,64 @@
|
||||||
/* Bra.h -- Branch converters for executables
|
/* Bra.h -- Branch converters for executables
|
||||||
2024-01-20 : Igor Pavlov : Public domain */
|
2013-01-18 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_INC_BRA_H
|
#ifndef __BRA_H
|
||||||
#define ZIP7_INC_BRA_H
|
#define __BRA_H
|
||||||
|
|
||||||
#include "7zTypes.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
EXTERN_C_BEGIN
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
/* #define PPC BAD_PPC_11 // for debug */
|
|
||||||
|
|
||||||
#define Z7_BRANCH_CONV_DEC_2(name) z7_ ## name ## _Dec
|
|
||||||
#define Z7_BRANCH_CONV_ENC_2(name) z7_ ## name ## _Enc
|
|
||||||
#define Z7_BRANCH_CONV_DEC(name) Z7_BRANCH_CONV_DEC_2(BranchConv_ ## name)
|
|
||||||
#define Z7_BRANCH_CONV_ENC(name) Z7_BRANCH_CONV_ENC_2(BranchConv_ ## name)
|
|
||||||
#define Z7_BRANCH_CONV_ST_DEC(name) z7_BranchConvSt_ ## name ## _Dec
|
|
||||||
#define Z7_BRANCH_CONV_ST_ENC(name) z7_BranchConvSt_ ## name ## _Enc
|
|
||||||
|
|
||||||
#define Z7_BRANCH_CONV_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc)
|
|
||||||
#define Z7_BRANCH_CONV_ST_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc, UInt32 *state)
|
|
||||||
|
|
||||||
typedef Z7_BRANCH_CONV_DECL( (*z7_Func_BranchConv));
|
|
||||||
typedef Z7_BRANCH_CONV_ST_DECL((*z7_Func_BranchConvSt));
|
|
||||||
|
|
||||||
#define Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL 0
|
|
||||||
Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_DEC(X86));
|
|
||||||
Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_ENC(X86));
|
|
||||||
|
|
||||||
#define Z7_BRANCH_FUNCS_DECL(name) \
|
|
||||||
Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_DEC_2(name)); \
|
|
||||||
Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_ENC_2(name));
|
|
||||||
|
|
||||||
Z7_BRANCH_FUNCS_DECL (BranchConv_ARM64)
|
|
||||||
Z7_BRANCH_FUNCS_DECL (BranchConv_ARM)
|
|
||||||
Z7_BRANCH_FUNCS_DECL (BranchConv_ARMT)
|
|
||||||
Z7_BRANCH_FUNCS_DECL (BranchConv_PPC)
|
|
||||||
Z7_BRANCH_FUNCS_DECL (BranchConv_SPARC)
|
|
||||||
Z7_BRANCH_FUNCS_DECL (BranchConv_IA64)
|
|
||||||
Z7_BRANCH_FUNCS_DECL (BranchConv_RISCV)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These functions convert data that contain CPU instructions.
|
These functions convert relative addresses to absolute addresses
|
||||||
Each such function converts relative addresses to absolute addresses in some
|
in CALL instructions to increase the compression ratio.
|
||||||
branch instructions: CALL (in all converters) and JUMP (X86 converter only).
|
|
||||||
Such conversion allows to increase compression ratio, if we compress that data.
|
|
||||||
|
|
||||||
There are 2 types of converters:
|
In:
|
||||||
Byte * Conv_RISC (Byte *data, SizeT size, UInt32 pc);
|
data - data buffer
|
||||||
Byte * ConvSt_X86(Byte *data, SizeT size, UInt32 pc, UInt32 *state);
|
size - size of data
|
||||||
Each Converter supports 2 versions: one for encoding
|
ip - current virtual Instruction Pinter (IP) value
|
||||||
and one for decoding (_Enc/_Dec postfixes in function name).
|
state - state variable for x86 converter
|
||||||
|
encoding - 0 (for decoding), 1 (for encoding)
|
||||||
|
|
||||||
In params:
|
Out:
|
||||||
data : data buffer
|
state - state variable for x86 converter
|
||||||
size : size of data
|
|
||||||
pc : current virtual Program Counter (Instruction Pointer) value
|
|
||||||
In/Out param:
|
|
||||||
state : pointer to state variable (for X86 converter only)
|
|
||||||
|
|
||||||
Return:
|
Returns:
|
||||||
The pointer to position in (data) buffer after last byte that was processed.
|
The number of processed bytes. If you call these functions with multiple calls,
|
||||||
If the caller calls converter again, it must call it starting with that position.
|
you must start next call with first byte after block of processed bytes.
|
||||||
But the caller is allowed to move data in buffer. So pointer to
|
|
||||||
current processed position also will be changed for next call.
|
|
||||||
Also the caller must increase internal (pc) value for next call.
|
|
||||||
|
|
||||||
Each converter has some characteristics: Endian, Alignment, LookAhead.
|
|
||||||
Type Endian Alignment LookAhead
|
Type Endian Alignment LookAhead
|
||||||
|
|
||||||
X86 little 1 4
|
x86 little 1 4
|
||||||
ARMT little 2 2
|
ARMT little 2 2
|
||||||
RISCV little 2 6
|
|
||||||
ARM little 4 0
|
ARM little 4 0
|
||||||
ARM64 little 4 0
|
|
||||||
PPC big 4 0
|
PPC big 4 0
|
||||||
SPARC big 4 0
|
SPARC big 4 0
|
||||||
IA64 little 16 0
|
IA64 little 16 0
|
||||||
|
|
||||||
(data) must be aligned for (Alignment).
|
size must be >= Alignment + LookAhead, if it's not last block.
|
||||||
processed size can be calculated as:
|
If (size < Alignment + LookAhead), converter returns 0.
|
||||||
SizeT processed = Conv(data, size, pc) - data;
|
|
||||||
if (processed == 0)
|
|
||||||
it means that converter needs more data for processing.
|
|
||||||
If (size < Alignment + LookAhead)
|
|
||||||
then (processed == 0) is allowed.
|
|
||||||
|
|
||||||
Example code for conversion in loop:
|
Example:
|
||||||
UInt32 pc = 0;
|
|
||||||
size = 0;
|
UInt32 ip = 0;
|
||||||
for (;;)
|
for ()
|
||||||
{
|
{
|
||||||
size += Load_more_input_data(data + size);
|
; size must be >= Alignment + LookAhead, if it's not last block
|
||||||
SizeT processed = Conv(data, size, pc) - data;
|
SizeT processed = Convert(data, size, ip, 1);
|
||||||
if (processed == 0 && no_more_input_data_after_size)
|
|
||||||
break; // we stop convert loop
|
|
||||||
data += processed;
|
data += processed;
|
||||||
size -= processed;
|
size -= processed;
|
||||||
pc += processed;
|
ip += processed;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define x86_Convert_Init(state) { state = 0; }
|
||||||
|
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
|
||||||
|
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,187 +1,82 @@
|
||||||
/* Bra86.c -- Branch converter for X86 code (BCJ)
|
/* Bra86.c -- Converter for x86 code (BCJ)
|
||||||
2023-04-02 : Igor Pavlov : Public domain */
|
2021-02-09 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
#include "CpuArch.h"
|
|
||||||
|
|
||||||
|
#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
|
||||||
|
|
||||||
#if defined(MY_CPU_SIZEOF_POINTER) \
|
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
||||||
&& ( MY_CPU_SIZEOF_POINTER == 4 \
|
|
||||||
|| MY_CPU_SIZEOF_POINTER == 8)
|
|
||||||
#define BR_CONV_USE_OPT_PC_PTR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BR_CONV_USE_OPT_PC_PTR
|
|
||||||
#define BR_PC_INIT pc -= (UInt32)(SizeT)p; // (MY_uintptr_t)
|
|
||||||
#define BR_PC_GET (pc + (UInt32)(SizeT)p)
|
|
||||||
#else
|
|
||||||
#define BR_PC_INIT pc += (UInt32)size;
|
|
||||||
#define BR_PC_GET (pc - (UInt32)(SizeT)(lim - p))
|
|
||||||
// #define BR_PC_INIT
|
|
||||||
// #define BR_PC_GET (pc + (UInt32)(SizeT)(p - data))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BR_CONVERT_VAL(v, c) if (encoding) v += c; else v -= c;
|
|
||||||
// #define BR_CONVERT_VAL(v, c) if (!encoding) c = (UInt32)0 - c; v += c;
|
|
||||||
|
|
||||||
#define Z7_BRANCH_CONV_ST(name) z7_BranchConvSt_ ## name
|
|
||||||
|
|
||||||
#define BR86_NEED_CONV_FOR_MS_BYTE(b) ((((b) + 1) & 0xfe) == 0)
|
|
||||||
|
|
||||||
#ifdef MY_CPU_LE_UNALIGN
|
|
||||||
#define BR86_PREPARE_BCJ_SCAN const UInt32 v = GetUi32(p) ^ 0xe8e8e8e8;
|
|
||||||
#define BR86_IS_BCJ_BYTE(n) ((v & ((UInt32)0xfe << (n) * 8)) == 0)
|
|
||||||
#else
|
|
||||||
#define BR86_PREPARE_BCJ_SCAN
|
|
||||||
// bad for MSVC X86 (partial write to byte reg):
|
|
||||||
#define BR86_IS_BCJ_BYTE(n) ((p[n - 4] & 0xfe) == 0xe8)
|
|
||||||
// bad for old MSVC (partial write to byte reg):
|
|
||||||
// #define BR86_IS_BCJ_BYTE(n) (((*p ^ 0xe8) & 0xfe) == 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static
|
|
||||||
Z7_FORCE_INLINE
|
|
||||||
Z7_ATTRIB_NO_VECTOR
|
|
||||||
Byte *Z7_BRANCH_CONV_ST(X86)(Byte *p, SizeT size, UInt32 pc, UInt32 *state, int encoding)
|
|
||||||
{
|
{
|
||||||
|
SizeT pos = 0;
|
||||||
|
UInt32 mask = *state & 7;
|
||||||
if (size < 5)
|
if (size < 5)
|
||||||
return p;
|
return 0;
|
||||||
{
|
size -= 4;
|
||||||
// Byte *p = data;
|
ip += 5;
|
||||||
const Byte *lim = p + size - 4;
|
|
||||||
unsigned mask = (unsigned)*state; // & 7;
|
|
||||||
#ifdef BR_CONV_USE_OPT_PC_PTR
|
|
||||||
/* if BR_CONV_USE_OPT_PC_PTR is defined: we need to adjust (pc) for (+4),
|
|
||||||
because call/jump offset is relative to the next instruction.
|
|
||||||
if BR_CONV_USE_OPT_PC_PTR is not defined : we don't need to adjust (pc) for (+4),
|
|
||||||
because BR_PC_GET uses (pc - (lim - p)), and lim was adjusted for (-4) before.
|
|
||||||
*/
|
|
||||||
pc += 4;
|
|
||||||
#endif
|
|
||||||
BR_PC_INIT
|
|
||||||
goto start;
|
|
||||||
|
|
||||||
for (;; mask |= 4)
|
for (;;)
|
||||||
{
|
{
|
||||||
// cont: mask |= 4;
|
Byte *p = data + pos;
|
||||||
start:
|
const Byte *limit = data + size;
|
||||||
if (p >= lim)
|
for (; p < limit; p++)
|
||||||
goto fin;
|
if ((*p & 0xFE) == 0xE8)
|
||||||
|
break;
|
||||||
|
|
||||||
{
|
{
|
||||||
BR86_PREPARE_BCJ_SCAN
|
SizeT d = (SizeT)(p - data) - pos;
|
||||||
p += 4;
|
pos = (SizeT)(p - data);
|
||||||
if (BR86_IS_BCJ_BYTE(0)) { goto m0; } mask >>= 1;
|
if (p >= limit)
|
||||||
if (BR86_IS_BCJ_BYTE(1)) { goto m1; } mask >>= 1;
|
{
|
||||||
if (BR86_IS_BCJ_BYTE(2)) { goto m2; } mask = 0;
|
*state = (d > 2 ? 0 : mask >> (unsigned)d);
|
||||||
if (BR86_IS_BCJ_BYTE(3)) { goto a3; }
|
return pos;
|
||||||
}
|
}
|
||||||
goto main_loop;
|
if (d > 2)
|
||||||
|
mask = 0;
|
||||||
m0: p--;
|
else
|
||||||
m1: p--;
|
|
||||||
m2: p--;
|
|
||||||
if (mask == 0)
|
|
||||||
goto a3;
|
|
||||||
if (p > lim)
|
|
||||||
goto fin_p;
|
|
||||||
|
|
||||||
// if (((0x17u >> mask) & 1) == 0)
|
|
||||||
if (mask > 4 || mask == 3)
|
|
||||||
{
|
{
|
||||||
mask >>= 1;
|
mask >>= (unsigned)d;
|
||||||
continue; // goto cont;
|
if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
|
||||||
|
{
|
||||||
|
mask = (mask >> 1) | 4;
|
||||||
|
pos++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
mask >>= 1;
|
}
|
||||||
if (BR86_NEED_CONV_FOR_MS_BYTE(p[mask]))
|
}
|
||||||
continue; // goto cont;
|
|
||||||
// if (!BR86_NEED_CONV_FOR_MS_BYTE(p[3])) continue; // goto cont;
|
if (Test86MSByte(p[4]))
|
||||||
{
|
{
|
||||||
UInt32 v = GetUi32(p);
|
UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
||||||
UInt32 c;
|
UInt32 cur = ip + (UInt32)pos;
|
||||||
v += (1 << 24); if (v & 0xfe000000) continue; // goto cont;
|
pos += 5;
|
||||||
c = BR_PC_GET;
|
if (encoding)
|
||||||
BR_CONVERT_VAL(v, c)
|
v += cur;
|
||||||
|
else
|
||||||
|
v -= cur;
|
||||||
|
if (mask != 0)
|
||||||
{
|
{
|
||||||
mask <<= 3;
|
unsigned sh = (mask & 6) << 2;
|
||||||
if (BR86_NEED_CONV_FOR_MS_BYTE(v >> mask))
|
if (Test86MSByte((Byte)(v >> sh)))
|
||||||
{
|
{
|
||||||
v ^= (((UInt32)0x100 << mask) - 1);
|
v ^= (((UInt32)0x100 << sh) - 1);
|
||||||
#ifdef MY_CPU_X86
|
if (encoding)
|
||||||
// for X86 : we can recalculate (c) to reduce register pressure
|
v += cur;
|
||||||
c = BR_PC_GET;
|
else
|
||||||
#endif
|
v -= cur;
|
||||||
BR_CONVERT_VAL(v, c)
|
|
||||||
}
|
}
|
||||||
mask = 0;
|
mask = 0;
|
||||||
}
|
}
|
||||||
// v = (v & ((1 << 24) - 1)) - (v & (1 << 24));
|
p[1] = (Byte)v;
|
||||||
v &= (1 << 25) - 1; v -= (1 << 24);
|
p[2] = (Byte)(v >> 8);
|
||||||
SetUi32(p, v)
|
p[3] = (Byte)(v >> 16);
|
||||||
p += 4;
|
p[4] = (Byte)(0 - ((v >> 24) & 1));
|
||||||
goto main_loop;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
main_loop:
|
|
||||||
if (p >= lim)
|
|
||||||
goto fin;
|
|
||||||
for (;;)
|
|
||||||
{
|
{
|
||||||
BR86_PREPARE_BCJ_SCAN
|
mask = (mask >> 1) | 4;
|
||||||
p += 4;
|
pos++;
|
||||||
if (BR86_IS_BCJ_BYTE(0)) { goto a0; }
|
|
||||||
if (BR86_IS_BCJ_BYTE(1)) { goto a1; }
|
|
||||||
if (BR86_IS_BCJ_BYTE(2)) { goto a2; }
|
|
||||||
if (BR86_IS_BCJ_BYTE(3)) { goto a3; }
|
|
||||||
if (p >= lim)
|
|
||||||
goto fin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a0: p--;
|
|
||||||
a1: p--;
|
|
||||||
a2: p--;
|
|
||||||
a3:
|
|
||||||
if (p > lim)
|
|
||||||
goto fin_p;
|
|
||||||
// if (!BR86_NEED_CONV_FOR_MS_BYTE(p[3])) continue; // goto cont;
|
|
||||||
{
|
|
||||||
UInt32 v = GetUi32(p);
|
|
||||||
UInt32 c;
|
|
||||||
v += (1 << 24); if (v & 0xfe000000) continue; // goto cont;
|
|
||||||
c = BR_PC_GET;
|
|
||||||
BR_CONVERT_VAL(v, c)
|
|
||||||
// v = (v & ((1 << 24) - 1)) - (v & (1 << 24));
|
|
||||||
v &= (1 << 25) - 1; v -= (1 << 24);
|
|
||||||
SetUi32(p, v)
|
|
||||||
p += 4;
|
|
||||||
goto main_loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fin_p:
|
|
||||||
p--;
|
|
||||||
fin:
|
|
||||||
// the following processing for tail is optional and can be commented
|
|
||||||
/*
|
|
||||||
lim += 4;
|
|
||||||
for (; p < lim; p++, mask >>= 1)
|
|
||||||
if ((*p & 0xfe) == 0xe8)
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
*state = (UInt32)mask;
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define Z7_BRANCH_CONV_ST_FUNC_IMP(name, m, encoding) \
|
|
||||||
Z7_NO_INLINE \
|
|
||||||
Z7_ATTRIB_NO_VECTOR \
|
|
||||||
Byte *m(name)(Byte *data, SizeT size, UInt32 pc, UInt32 *state) \
|
|
||||||
{ return Z7_BRANCH_CONV_ST(name)(data, size, pc, state, encoding); }
|
|
||||||
|
|
||||||
Z7_BRANCH_CONV_ST_FUNC_IMP(X86, Z7_BRANCH_CONV_ST_DEC, 0)
|
|
||||||
#ifndef Z7_EXTRACT_ONLY
|
|
||||||
Z7_BRANCH_CONV_ST_FUNC_IMP(X86, Z7_BRANCH_CONV_ST_ENC, 1)
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,105 +1,12 @@
|
||||||
/* Compiler.h : Compiler specific defines and pragmas
|
/* Compiler.h
|
||||||
2024-01-22 : Igor Pavlov : Public domain */
|
2021-01-05 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_INC_COMPILER_H
|
#ifndef __7Z_COMPILER_H
|
||||||
#define ZIP7_INC_COMPILER_H
|
#define __7Z_COMPILER_H
|
||||||
|
|
||||||
#if defined(__clang__)
|
#ifdef __clang__
|
||||||
# define Z7_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
|
#pragma clang diagnostic ignored "-Wunused-private-field"
|
||||||
#endif
|
|
||||||
#if defined(__clang__) && defined(__apple_build_version__)
|
|
||||||
# define Z7_APPLE_CLANG_VERSION Z7_CLANG_VERSION
|
|
||||||
#elif defined(__clang__)
|
|
||||||
# define Z7_LLVM_CLANG_VERSION Z7_CLANG_VERSION
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
# define Z7_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#if !defined(__clang__) && !defined(__GNUC__)
|
|
||||||
#define Z7_MSC_VER_ORIGINAL _MSC_VER
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
|
||||||
#define Z7_MINGW
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__LCC__) && (defined(__MCST__) || defined(__e2k__))
|
|
||||||
#define Z7_MCST_LCC
|
|
||||||
#define Z7_MCST_LCC_VERSION (__LCC__ * 100 + __LCC_MINOR__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
#if defined(__AVX2__) \
|
|
||||||
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \
|
|
||||||
|| defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \
|
|
||||||
|| defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \
|
|
||||||
|| defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \
|
|
||||||
|| defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400)
|
|
||||||
#define Z7_COMPILER_AVX2_SUPPORTED
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
// #pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
|
||||||
|
|
||||||
#ifdef __clang__
|
|
||||||
// padding size of '' with 4 bytes to alignment boundary
|
|
||||||
#pragma GCC diagnostic ignored "-Wpadded"
|
|
||||||
|
|
||||||
#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) \
|
|
||||||
&& defined(__FreeBSD__)
|
|
||||||
// freebsd:
|
|
||||||
#pragma GCC diagnostic ignored "-Wexcess-padding"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __clang_major__ >= 16
|
|
||||||
#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __clang_major__ == 13
|
|
||||||
#if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16)
|
|
||||||
// cheri
|
|
||||||
#pragma GCC diagnostic ignored "-Wcapability-to-integer-cast"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __clang_major__ == 13
|
|
||||||
// for <arm_neon.h>
|
|
||||||
#pragma GCC diagnostic ignored "-Wreserved-identifier"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __clang__
|
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(__clang__) && __clang_major__ >= 16
|
|
||||||
// #pragma GCC diagnostic ignored "-Wcast-function-type-strict"
|
|
||||||
#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION \
|
|
||||||
_Pragma("GCC diagnostic ignored \"-Wcast-function-type-strict\"")
|
|
||||||
#else
|
|
||||||
#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void (*Z7_void_Function)(void);
|
|
||||||
#if defined(__clang__) || defined(__GNUC__)
|
|
||||||
#define Z7_CAST_FUNC_C (Z7_void_Function)
|
|
||||||
#elif defined(_MSC_VER) && _MSC_VER > 1920
|
|
||||||
#define Z7_CAST_FUNC_C (void *)
|
|
||||||
// #pragma warning(disable : 4191) // 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)()'
|
|
||||||
#else
|
|
||||||
#define Z7_CAST_FUNC_C
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
#if (defined(__GNUC__) && (__GNUC__ >= 8)) || defined(__clang__)
|
|
||||||
// #pragma GCC diagnostic ignored "-Wcast-function-type"
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40000) && (Z7_GCC_VERSION < 70000)
|
|
||||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
@ -110,124 +17,24 @@ typedef void (*Z7_void_Function)(void);
|
||||||
#pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
|
#pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER >= 1800
|
#if _MSC_VER >= 1300
|
||||||
#pragma warning(disable : 4464) // relative include path contains '..'
|
#pragma warning(disable : 4996) // This function or variable may be unsafe
|
||||||
#endif
|
#else
|
||||||
|
#pragma warning(disable : 4511) // copy constructor could not be generated
|
||||||
|
#pragma warning(disable : 4512) // assignment operator could not be generated
|
||||||
|
#pragma warning(disable : 4514) // unreferenced inline function has been removed
|
||||||
|
#pragma warning(disable : 4702) // unreachable code
|
||||||
|
#pragma warning(disable : 4710) // not inlined
|
||||||
|
#pragma warning(disable : 4714) // function marked as __forceinline not inlined
|
||||||
|
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
|
||||||
|
#endif
|
||||||
|
|
||||||
// == 1200 : -O1 : for __forceinline
|
#ifdef __clang__
|
||||||
// >= 1900 : -O1 : for printf
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
#pragma warning(disable : 4710) // function not inlined
|
#pragma clang diagnostic ignored "-Wmicrosoft-exception-spec"
|
||||||
|
// #pragma clang diagnostic ignored "-Wreserved-id-macro"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if _MSC_VER < 1900
|
|
||||||
// winnt.h: 'Int64ShllMod32'
|
|
||||||
#pragma warning(disable : 4514) // unreferenced inline function has been removed
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if _MSC_VER < 1300
|
|
||||||
// #pragma warning(disable : 4702) // unreachable code
|
|
||||||
// Bra.c : -O1:
|
|
||||||
#pragma warning(disable : 4714) // function marked as __forceinline not inlined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
#if _MSC_VER > 1400 && _MSC_VER <= 1900
|
|
||||||
// strcat: This function or variable may be unsafe
|
|
||||||
// sysinfoapi.h: kit10: GetVersion was declared deprecated
|
|
||||||
#pragma warning(disable : 4996)
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if _MSC_VER > 1200
|
|
||||||
// -Wall warnings
|
|
||||||
|
|
||||||
#pragma warning(disable : 4711) // function selected for automatic inline expansion
|
|
||||||
#pragma warning(disable : 4820) // '2' bytes padding added after data member
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400 && _MSC_VER < 1920
|
|
||||||
// 1400: string.h: _DBG_MEMCPY_INLINE_
|
|
||||||
// 1600 - 191x : smmintrin.h __cplusplus'
|
|
||||||
// is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
|
|
||||||
#pragma warning(disable : 4668)
|
|
||||||
|
|
||||||
// 1400 - 1600 : WinDef.h : 'FARPROC' :
|
|
||||||
// 1900 - 191x : immintrin.h: _readfsbase_u32
|
|
||||||
// no function prototype given : converting '()' to '(void)'
|
|
||||||
#pragma warning(disable : 4255)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1914
|
|
||||||
// Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
|
|
||||||
#pragma warning(disable : 5045)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // _MSC_VER > 1200
|
|
||||||
#endif // _MSC_VER
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__clang__) && (__clang_major__ >= 4)
|
|
||||||
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \
|
|
||||||
_Pragma("clang loop unroll(disable)") \
|
|
||||||
_Pragma("clang loop vectorize(disable)")
|
|
||||||
#define Z7_ATTRIB_NO_VECTORIZE
|
|
||||||
#elif defined(__GNUC__) && (__GNUC__ >= 5) \
|
|
||||||
&& (!defined(Z7_MCST_LCC_VERSION) || (Z7_MCST_LCC_VERSION >= 12610))
|
|
||||||
#define Z7_ATTRIB_NO_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
|
|
||||||
// __attribute__((optimize("no-unroll-loops")));
|
|
||||||
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE
|
|
||||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1920)
|
|
||||||
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \
|
|
||||||
_Pragma("loop( no_vector )")
|
|
||||||
#define Z7_ATTRIB_NO_VECTORIZE
|
|
||||||
#else
|
|
||||||
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE
|
|
||||||
#define Z7_ATTRIB_NO_VECTORIZE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MY_CPU_X86_OR_AMD64) && ( \
|
|
||||||
defined(__clang__) && (__clang_major__ >= 4) \
|
|
||||||
|| defined(__GNUC__) && (__GNUC__ >= 5))
|
|
||||||
#define Z7_ATTRIB_NO_SSE __attribute__((__target__("no-sse")))
|
|
||||||
#else
|
|
||||||
#define Z7_ATTRIB_NO_SSE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define Z7_ATTRIB_NO_VECTOR \
|
|
||||||
Z7_ATTRIB_NO_VECTORIZE \
|
|
||||||
Z7_ATTRIB_NO_SSE
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__clang__) && (__clang_major__ >= 8) \
|
|
||||||
|| defined(__GNUC__) && (__GNUC__ >= 1000) \
|
|
||||||
/* || defined(_MSC_VER) && (_MSC_VER >= 1920) */
|
|
||||||
// GCC is not good for __builtin_expect()
|
|
||||||
#define Z7_LIKELY(x) (__builtin_expect((x), 1))
|
|
||||||
#define Z7_UNLIKELY(x) (__builtin_expect((x), 0))
|
|
||||||
// #define Z7_unlikely [[unlikely]]
|
|
||||||
// #define Z7_likely [[likely]]
|
|
||||||
#else
|
|
||||||
#define Z7_LIKELY(x) (x)
|
|
||||||
#define Z7_UNLIKELY(x) (x)
|
|
||||||
// #define Z7_likely
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30600))
|
|
||||||
|
|
||||||
#if (Z7_CLANG_VERSION < 130000)
|
|
||||||
#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \
|
|
||||||
_Pragma("GCC diagnostic push") \
|
|
||||||
_Pragma("GCC diagnostic ignored \"-Wreserved-id-macro\"")
|
|
||||||
#else
|
|
||||||
#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \
|
|
||||||
_Pragma("GCC diagnostic push") \
|
|
||||||
_Pragma("GCC diagnostic ignored \"-Wreserved-macro-identifier\"")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER \
|
|
||||||
_Pragma("GCC diagnostic pop")
|
|
||||||
#else
|
|
||||||
#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
|
|
||||||
#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UNUSED_VAR(x) (void)x;
|
#define UNUSED_VAR(x) (void)x;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,8 @@
|
||||||
/* CpuArch.h -- CPU specific code
|
/* CpuArch.h -- CPU specific code
|
||||||
Igor Pavlov : Public domain */
|
2022-07-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_INC_CPU_ARCH_H
|
#ifndef __CPU_ARCH_H
|
||||||
#define ZIP7_INC_CPU_ARCH_H
|
#define __CPU_ARCH_H
|
||||||
|
|
||||||
#include "7zTypes.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||||||
MY_CPU_64BIT doesn't mean that (sizeof(void *) == 8)
|
MY_CPU_64BIT doesn't mean that (sizeof(void *) == 8)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(_M_ARM64EC)
|
|
||||||
#if defined(_M_X64) \
|
#if defined(_M_X64) \
|
||||||
|| defined(_M_AMD64) \
|
|| defined(_M_AMD64) \
|
||||||
|| defined(__x86_64__) \
|
|| defined(__x86_64__) \
|
||||||
|
@ -36,7 +35,6 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||||||
#endif
|
#endif
|
||||||
#define MY_CPU_64BIT
|
#define MY_CPU_64BIT
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(_M_IX86) \
|
#if defined(_M_IX86) \
|
||||||
|
@ -49,26 +47,11 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||||||
|
|
||||||
|
|
||||||
#if defined(_M_ARM64) \
|
#if defined(_M_ARM64) \
|
||||||
|| defined(_M_ARM64EC) \
|
|
||||||
|| defined(__AARCH64EL__) \
|
|| defined(__AARCH64EL__) \
|
||||||
|| defined(__AARCH64EB__) \
|
|| defined(__AARCH64EB__) \
|
||||||
|| defined(__aarch64__)
|
|| defined(__aarch64__)
|
||||||
#define MY_CPU_ARM64
|
#define MY_CPU_ARM64
|
||||||
#if defined(__ILP32__) \
|
|
||||||
|| defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4)
|
|
||||||
#define MY_CPU_NAME "arm64-32"
|
|
||||||
#define MY_CPU_SIZEOF_POINTER 4
|
|
||||||
#elif defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16)
|
|
||||||
#define MY_CPU_NAME "arm64-128"
|
|
||||||
#define MY_CPU_SIZEOF_POINTER 16
|
|
||||||
#else
|
|
||||||
#if defined(_M_ARM64EC)
|
|
||||||
#define MY_CPU_NAME "arm64ec"
|
|
||||||
#else
|
|
||||||
#define MY_CPU_NAME "arm64"
|
#define MY_CPU_NAME "arm64"
|
||||||
#endif
|
|
||||||
#define MY_CPU_SIZEOF_POINTER 8
|
|
||||||
#endif
|
|
||||||
#define MY_CPU_64BIT
|
#define MY_CPU_64BIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -85,10 +68,8 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||||||
#define MY_CPU_ARM
|
#define MY_CPU_ARM
|
||||||
|
|
||||||
#if defined(__thumb__) || defined(__THUMBEL__) || defined(_M_ARMT)
|
#if defined(__thumb__) || defined(__THUMBEL__) || defined(_M_ARMT)
|
||||||
#define MY_CPU_ARMT
|
|
||||||
#define MY_CPU_NAME "armt"
|
#define MY_CPU_NAME "armt"
|
||||||
#else
|
#else
|
||||||
#define MY_CPU_ARM32
|
|
||||||
#define MY_CPU_NAME "arm"
|
#define MY_CPU_NAME "arm"
|
||||||
#endif
|
#endif
|
||||||
/* #define MY_CPU_32BIT */
|
/* #define MY_CPU_32BIT */
|
||||||
|
@ -122,8 +103,6 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||||||
|| defined(__PPC__) \
|
|| defined(__PPC__) \
|
||||||
|| defined(_POWER)
|
|| defined(_POWER)
|
||||||
|
|
||||||
#define MY_CPU_PPC_OR_PPC64
|
|
||||||
|
|
||||||
#if defined(__ppc64__) \
|
#if defined(__ppc64__) \
|
||||||
|| defined(__powerpc64__) \
|
|| defined(__powerpc64__) \
|
||||||
|| defined(_LP64) \
|
|| defined(_LP64) \
|
||||||
|
@ -144,36 +123,8 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(__sparc__) \
|
|
||||||
|| defined(__sparc)
|
|
||||||
#define MY_CPU_SPARC
|
|
||||||
#if defined(__LP64__) \
|
|
||||||
|| defined(_LP64) \
|
|
||||||
|| defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8)
|
|
||||||
#define MY_CPU_NAME "sparcv9"
|
|
||||||
#define MY_CPU_SIZEOF_POINTER 8
|
|
||||||
#define MY_CPU_64BIT
|
|
||||||
#elif defined(__sparc_v9__) \
|
|
||||||
|| defined(__sparcv9)
|
|
||||||
#define MY_CPU_64BIT
|
|
||||||
#if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4)
|
|
||||||
#define MY_CPU_NAME "sparcv9-32"
|
|
||||||
#else
|
|
||||||
#define MY_CPU_NAME "sparcv9m"
|
|
||||||
#endif
|
|
||||||
#elif defined(__sparc_v8__) \
|
|
||||||
|| defined(__sparcv8)
|
|
||||||
#define MY_CPU_NAME "sparcv8"
|
|
||||||
#define MY_CPU_SIZEOF_POINTER 4
|
|
||||||
#else
|
|
||||||
#define MY_CPU_NAME "sparc"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__riscv) \
|
#if defined(__riscv) \
|
||||||
|| defined(__riscv__)
|
|| defined(__riscv__)
|
||||||
#define MY_CPU_RISCV
|
|
||||||
#if __riscv_xlen == 32
|
#if __riscv_xlen == 32
|
||||||
#define MY_CPU_NAME "riscv32"
|
#define MY_CPU_NAME "riscv32"
|
||||||
#elif __riscv_xlen == 64
|
#elif __riscv_xlen == 64
|
||||||
|
@ -184,39 +135,6 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(__loongarch__)
|
|
||||||
#define MY_CPU_LOONGARCH
|
|
||||||
#if defined(__loongarch64) || defined(__loongarch_grlen) && (__loongarch_grlen == 64)
|
|
||||||
#define MY_CPU_64BIT
|
|
||||||
#endif
|
|
||||||
#if defined(__loongarch64)
|
|
||||||
#define MY_CPU_NAME "loongarch64"
|
|
||||||
#define MY_CPU_LOONGARCH64
|
|
||||||
#else
|
|
||||||
#define MY_CPU_NAME "loongarch"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// #undef MY_CPU_NAME
|
|
||||||
// #undef MY_CPU_SIZEOF_POINTER
|
|
||||||
// #define __e2k__
|
|
||||||
// #define __SIZEOF_POINTER__ 4
|
|
||||||
#if defined(__e2k__)
|
|
||||||
#define MY_CPU_E2K
|
|
||||||
#if defined(__ILP32__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4)
|
|
||||||
#define MY_CPU_NAME "e2k-32"
|
|
||||||
#define MY_CPU_SIZEOF_POINTER 4
|
|
||||||
#else
|
|
||||||
#define MY_CPU_NAME "e2k"
|
|
||||||
#if defined(__LP64__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8)
|
|
||||||
#define MY_CPU_SIZEOF_POINTER 8
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#define MY_CPU_64BIT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
||||||
#define MY_CPU_X86_OR_AMD64
|
#define MY_CPU_X86_OR_AMD64
|
||||||
#endif
|
#endif
|
||||||
|
@ -247,7 +165,6 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||||||
|| defined(MY_CPU_ARM_LE) \
|
|| defined(MY_CPU_ARM_LE) \
|
||||||
|| defined(MY_CPU_ARM64_LE) \
|
|| defined(MY_CPU_ARM64_LE) \
|
||||||
|| defined(MY_CPU_IA64_LE) \
|
|| defined(MY_CPU_IA64_LE) \
|
||||||
|| defined(_LITTLE_ENDIAN) \
|
|
||||||
|| defined(__LITTLE_ENDIAN__) \
|
|| defined(__LITTLE_ENDIAN__) \
|
||||||
|| defined(__ARMEL__) \
|
|| defined(__ARMEL__) \
|
||||||
|| defined(__THUMBEL__) \
|
|| defined(__THUMBEL__) \
|
||||||
|
@ -280,9 +197,6 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||||||
#error Stop_Compiling_Bad_Endian
|
#error Stop_Compiling_Bad_Endian
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(MY_CPU_LE) && !defined(MY_CPU_BE)
|
|
||||||
#error Stop_Compiling_CPU_ENDIAN_must_be_detected_at_compile_time
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
|
#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
|
||||||
#error Stop_Compiling_Bad_32_64_BIT
|
#error Stop_Compiling_Bad_32_64_BIT
|
||||||
|
@ -324,7 +238,6 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||||||
|
|
||||||
|
|
||||||
#ifndef MY_CPU_NAME
|
#ifndef MY_CPU_NAME
|
||||||
// #define MY_CPU_IS_UNKNOWN
|
|
||||||
#ifdef MY_CPU_LE
|
#ifdef MY_CPU_LE
|
||||||
#define MY_CPU_NAME "LE"
|
#define MY_CPU_NAME "LE"
|
||||||
#elif defined(MY_CPU_BE)
|
#elif defined(MY_CPU_BE)
|
||||||
|
@ -340,121 +253,15 @@ MY_CPU_64BIT means that processor can work with 64-bit registers.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __has_builtin
|
|
||||||
#define Z7_has_builtin(x) __has_builtin(x)
|
|
||||||
#else
|
|
||||||
#define Z7_has_builtin(x) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define Z7_BSWAP32_CONST(v) \
|
|
||||||
( (((UInt32)(v) << 24) ) \
|
|
||||||
| (((UInt32)(v) << 8) & (UInt32)0xff0000) \
|
|
||||||
| (((UInt32)(v) >> 8) & (UInt32)0xff00 ) \
|
|
||||||
| (((UInt32)(v) >> 24) ))
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* Note: these macros will use bswap instruction (486), that is unsupported in 386 cpu */
|
|
||||||
|
|
||||||
#pragma intrinsic(_byteswap_ushort)
|
|
||||||
#pragma intrinsic(_byteswap_ulong)
|
|
||||||
#pragma intrinsic(_byteswap_uint64)
|
|
||||||
|
|
||||||
#define Z7_BSWAP16(v) _byteswap_ushort(v)
|
|
||||||
#define Z7_BSWAP32(v) _byteswap_ulong (v)
|
|
||||||
#define Z7_BSWAP64(v) _byteswap_uint64(v)
|
|
||||||
#define Z7_CPU_FAST_BSWAP_SUPPORTED
|
|
||||||
|
|
||||||
/* GCC can generate slow code that calls function for __builtin_bswap32() for:
|
|
||||||
- GCC for RISCV, if Zbb/XTHeadBb extension is not used.
|
|
||||||
- GCC for SPARC.
|
|
||||||
The code from CLANG for SPARC also is not fastest.
|
|
||||||
So we don't define Z7_CPU_FAST_BSWAP_SUPPORTED in some cases.
|
|
||||||
*/
|
|
||||||
#elif (!defined(MY_CPU_RISCV) || defined (__riscv_zbb) || defined(__riscv_xtheadbb)) \
|
|
||||||
&& !defined(MY_CPU_SPARC) \
|
|
||||||
&& ( \
|
|
||||||
(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|
|
||||||
|| (defined(__clang__) && Z7_has_builtin(__builtin_bswap16)) \
|
|
||||||
)
|
|
||||||
|
|
||||||
#define Z7_BSWAP16(v) __builtin_bswap16(v)
|
|
||||||
#define Z7_BSWAP32(v) __builtin_bswap32(v)
|
|
||||||
#define Z7_BSWAP64(v) __builtin_bswap64(v)
|
|
||||||
#define Z7_CPU_FAST_BSWAP_SUPPORTED
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define Z7_BSWAP16(v) ((UInt16) \
|
|
||||||
( ((UInt32)(v) << 8) \
|
|
||||||
| ((UInt32)(v) >> 8) \
|
|
||||||
))
|
|
||||||
|
|
||||||
#define Z7_BSWAP32(v) Z7_BSWAP32_CONST(v)
|
|
||||||
|
|
||||||
#define Z7_BSWAP64(v) \
|
|
||||||
( ( ( (UInt64)(v) ) << 8 * 7 ) \
|
|
||||||
| ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 1) ) << 8 * 5 ) \
|
|
||||||
| ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 2) ) << 8 * 3 ) \
|
|
||||||
| ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 3) ) << 8 * 1 ) \
|
|
||||||
| ( ( (UInt64)(v) >> 8 * 1 ) & ((UInt32)0xff << 8 * 3) ) \
|
|
||||||
| ( ( (UInt64)(v) >> 8 * 3 ) & ((UInt32)0xff << 8 * 2) ) \
|
|
||||||
| ( ( (UInt64)(v) >> 8 * 5 ) & ((UInt32)0xff << 8 * 1) ) \
|
|
||||||
| ( ( (UInt64)(v) >> 8 * 7 ) ) \
|
|
||||||
)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef MY_CPU_LE
|
#ifdef MY_CPU_LE
|
||||||
#if defined(MY_CPU_X86_OR_AMD64) \
|
#if defined(MY_CPU_X86_OR_AMD64) \
|
||||||
|| defined(MY_CPU_ARM64) \
|
|| defined(MY_CPU_ARM64)
|
||||||
|| defined(MY_CPU_RISCV) && defined(__riscv_misaligned_fast) \
|
|
||||||
|| defined(MY_CPU_E2K) && defined(__iset__) && (__iset__ >= 6)
|
|
||||||
#define MY_CPU_LE_UNALIGN
|
#define MY_CPU_LE_UNALIGN
|
||||||
#define MY_CPU_LE_UNALIGN_64
|
#define MY_CPU_LE_UNALIGN_64
|
||||||
#elif defined(__ARM_FEATURE_UNALIGNED)
|
#elif defined(__ARM_FEATURE_UNALIGNED)
|
||||||
/* === ALIGNMENT on 32-bit arm and LDRD/STRD/LDM/STM instructions.
|
/* gcc9 for 32-bit arm can use LDRD instruction that requires 32-bit alignment.
|
||||||
Description of problems:
|
So we can't use unaligned 64-bit operations. */
|
||||||
problem-1 : 32-bit ARM architecture:
|
#define MY_CPU_LE_UNALIGN
|
||||||
multi-access (pair of 32-bit accesses) instructions (LDRD/STRD/LDM/STM)
|
|
||||||
require 32-bit (WORD) alignment (by 32-bit ARM architecture).
|
|
||||||
So there is "Alignment fault exception", if data is not aligned for 32-bit.
|
|
||||||
|
|
||||||
problem-2 : 32-bit kernels and arm64 kernels:
|
|
||||||
32-bit linux kernels provide fixup for these "paired" instruction "Alignment fault exception".
|
|
||||||
So unaligned paired-access instructions work via exception handler in kernel in 32-bit linux.
|
|
||||||
|
|
||||||
But some arm64 kernels do not handle these faults in 32-bit programs.
|
|
||||||
So we have unhandled exception for such instructions.
|
|
||||||
Probably some new arm64 kernels have fixed it, and unaligned
|
|
||||||
paired-access instructions work in new kernels?
|
|
||||||
|
|
||||||
problem-3 : compiler for 32-bit arm:
|
|
||||||
Compilers use LDRD/STRD/LDM/STM for UInt64 accesses
|
|
||||||
and for another cases where two 32-bit accesses are fused
|
|
||||||
to one multi-access instruction.
|
|
||||||
So UInt64 variables must be aligned for 32-bit, and each
|
|
||||||
32-bit access must be aligned for 32-bit, if we want to
|
|
||||||
avoid "Alignment fault" exception (handled or unhandled).
|
|
||||||
|
|
||||||
problem-4 : performace:
|
|
||||||
Even if unaligned access is handled by kernel, it will be slow.
|
|
||||||
So if we allow unaligned access, we can get fast unaligned
|
|
||||||
single-access, and slow unaligned paired-access.
|
|
||||||
|
|
||||||
We don't allow unaligned access on 32-bit arm, because compiler
|
|
||||||
genarates paired-access instructions that require 32-bit alignment,
|
|
||||||
and some arm64 kernels have no handler for these instructions.
|
|
||||||
Also unaligned paired-access instructions will be slow, if kernel handles them.
|
|
||||||
*/
|
|
||||||
// it must be disabled:
|
|
||||||
// #define MY_CPU_LE_UNALIGN
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -465,11 +272,13 @@ problem-4 : performace:
|
||||||
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
|
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
|
||||||
#ifdef MY_CPU_LE_UNALIGN_64
|
#ifdef MY_CPU_LE_UNALIGN_64
|
||||||
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
|
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
|
||||||
#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); }
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); }
|
#define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); }
|
||||||
#define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); }
|
#define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); }
|
||||||
|
#ifdef MY_CPU_LE_UNALIGN_64
|
||||||
|
#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); }
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -496,33 +305,50 @@ problem-4 : performace:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef GetUi64
|
#ifndef MY_CPU_LE_UNALIGN_64
|
||||||
|
|
||||||
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SetUi64
|
|
||||||
#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
|
#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
|
||||||
SetUi32(_ppp2_ , (UInt32)_vvv2_) \
|
SetUi32(_ppp2_ , (UInt32)_vvv2_); \
|
||||||
SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)) }
|
SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(MY_CPU_LE_UNALIGN) && defined(Z7_CPU_FAST_BSWAP_SUPPORTED)
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// Z7_BSWAP16 can be slow for x86-msvc
|
#ifdef __has_builtin
|
||||||
#define GetBe16_to32(p) (Z7_BSWAP16 (*(const UInt16 *)(const void *)(p)))
|
#define MY__has_builtin(x) __has_builtin(x)
|
||||||
#else
|
#else
|
||||||
#define GetBe16_to32(p) (Z7_BSWAP32 (*(const UInt16 *)(const void *)(p)) >> 16)
|
#define MY__has_builtin(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GetBe32(p) Z7_BSWAP32 (*(const UInt32 *)(const void *)(p))
|
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ defined(_MSC_VER) && (_MSC_VER >= 1300)
|
||||||
#define SetBe32(p, v) { (*(UInt32 *)(void *)(p)) = Z7_BSWAP32(v); }
|
|
||||||
|
|
||||||
#if defined(MY_CPU_LE_UNALIGN_64)
|
/* Note: we use bswap instruction, that is unsupported in 386 cpu */
|
||||||
#define GetBe64(p) Z7_BSWAP64 (*(const UInt64 *)(const void *)(p))
|
|
||||||
#define SetBe64(p, v) { (*(UInt64 *)(void *)(p)) = Z7_BSWAP64(v); }
|
#include <stdlib.h>
|
||||||
#endif
|
|
||||||
|
#pragma intrinsic(_byteswap_ushort)
|
||||||
|
#pragma intrinsic(_byteswap_ulong)
|
||||||
|
#pragma intrinsic(_byteswap_uint64)
|
||||||
|
|
||||||
|
/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
|
||||||
|
#define GetBe32(p) _byteswap_ulong (*(const UInt32 *)(const void *)(p))
|
||||||
|
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const void *)(p))
|
||||||
|
|
||||||
|
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
|
||||||
|
|
||||||
|
#elif defined(MY_CPU_LE_UNALIGN) && ( \
|
||||||
|
(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|
||||||
|
|| (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
|
||||||
|
|
||||||
|
/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const void *)(p)) */
|
||||||
|
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const void *)(p))
|
||||||
|
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const void *)(p))
|
||||||
|
|
||||||
|
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -532,6 +358,8 @@ problem-4 : performace:
|
||||||
((UInt32)((const Byte *)(p))[2] << 8) | \
|
((UInt32)((const Byte *)(p))[2] << 8) | \
|
||||||
((const Byte *)(p))[3] )
|
((const Byte *)(p))[3] )
|
||||||
|
|
||||||
|
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||||
|
|
||||||
#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
||||||
_ppp_[0] = (Byte)(_vvv_ >> 24); \
|
_ppp_[0] = (Byte)(_vvv_ >> 24); \
|
||||||
_ppp_[1] = (Byte)(_vvv_ >> 16); \
|
_ppp_[1] = (Byte)(_vvv_ >> 16); \
|
||||||
|
@ -540,113 +368,53 @@ problem-4 : performace:
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GetBe64
|
|
||||||
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SetBe64
|
|
||||||
#define SetBe64(p, v) { Byte *_ppp_ = (Byte *)(p); UInt64 _vvv_ = (v); \
|
|
||||||
_ppp_[0] = (Byte)(_vvv_ >> 56); \
|
|
||||||
_ppp_[1] = (Byte)(_vvv_ >> 48); \
|
|
||||||
_ppp_[2] = (Byte)(_vvv_ >> 40); \
|
|
||||||
_ppp_[3] = (Byte)(_vvv_ >> 32); \
|
|
||||||
_ppp_[4] = (Byte)(_vvv_ >> 24); \
|
|
||||||
_ppp_[5] = (Byte)(_vvv_ >> 16); \
|
|
||||||
_ppp_[6] = (Byte)(_vvv_ >> 8); \
|
|
||||||
_ppp_[7] = (Byte)_vvv_; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GetBe16
|
#ifndef GetBe16
|
||||||
#ifdef GetBe16_to32
|
|
||||||
#define GetBe16(p) ( (UInt16) GetBe16_to32(p))
|
|
||||||
#else
|
|
||||||
#define GetBe16(p) ( (UInt16) ( \
|
#define GetBe16(p) ( (UInt16) ( \
|
||||||
((UInt16)((const Byte *)(p))[0] << 8) | \
|
((UInt16)((const Byte *)(p))[0] << 8) | \
|
||||||
((const Byte *)(p))[1] ))
|
((const Byte *)(p))[1] ))
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(MY_CPU_BE)
|
|
||||||
#define Z7_CONV_BE_TO_NATIVE_CONST32(v) (v)
|
|
||||||
#define Z7_CONV_LE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v)
|
|
||||||
#define Z7_CONV_NATIVE_TO_BE_32(v) (v)
|
|
||||||
#elif defined(MY_CPU_LE)
|
|
||||||
#define Z7_CONV_BE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v)
|
|
||||||
#define Z7_CONV_LE_TO_NATIVE_CONST32(v) (v)
|
|
||||||
#define Z7_CONV_NATIVE_TO_BE_32(v) Z7_BSWAP32(v)
|
|
||||||
#else
|
|
||||||
#error Stop_Compiling_Unknown_Endian_CONV
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(MY_CPU_BE)
|
|
||||||
|
|
||||||
#define GetBe64a(p) (*(const UInt64 *)(const void *)(p))
|
|
||||||
#define GetBe32a(p) (*(const UInt32 *)(const void *)(p))
|
|
||||||
#define GetBe16a(p) (*(const UInt16 *)(const void *)(p))
|
|
||||||
#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
|
|
||||||
#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
|
|
||||||
|
|
||||||
#define GetUi64a(p) GetUi64(p)
|
|
||||||
#define GetUi32a(p) GetUi32(p)
|
|
||||||
#define GetUi16a(p) GetUi16(p)
|
|
||||||
#define SetUi32a(p, v) SetUi32(p, v)
|
|
||||||
#define SetUi16a(p, v) SetUi16(p, v)
|
|
||||||
|
|
||||||
#elif defined(MY_CPU_LE)
|
|
||||||
|
|
||||||
#define GetUi64a(p) (*(const UInt64 *)(const void *)(p))
|
|
||||||
#define GetUi32a(p) (*(const UInt32 *)(const void *)(p))
|
|
||||||
#define GetUi16a(p) (*(const UInt16 *)(const void *)(p))
|
|
||||||
#define SetUi32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
|
|
||||||
#define SetUi16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
|
|
||||||
|
|
||||||
#define GetBe64a(p) GetBe64(p)
|
|
||||||
#define GetBe32a(p) GetBe32(p)
|
|
||||||
#define GetBe16a(p) GetBe16(p)
|
|
||||||
#define SetBe32a(p, v) SetBe32(p, v)
|
|
||||||
#define SetBe16a(p, v) SetBe16(p, v)
|
|
||||||
|
|
||||||
#else
|
|
||||||
#error Stop_Compiling_Unknown_Endian_CPU_a
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef GetBe16_to32
|
|
||||||
#define GetBe16_to32(p) GetBe16(p)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(MY_CPU_X86_OR_AMD64) \
|
|
||||||
|| defined(MY_CPU_ARM_OR_ARM64) \
|
|
||||||
|| defined(MY_CPU_PPC_OR_PPC64)
|
|
||||||
#define Z7_CPU_FAST_ROTATE_SUPPORTED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
|
|
||||||
void Z7_FASTCALL z7_x86_cpuid(UInt32 a[4], UInt32 function);
|
typedef struct
|
||||||
UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void);
|
{
|
||||||
#if defined(MY_CPU_AMD64)
|
UInt32 maxFunc;
|
||||||
#define Z7_IF_X86_CPUID_SUPPORTED
|
UInt32 vendor[3];
|
||||||
#else
|
UInt32 ver;
|
||||||
#define Z7_IF_X86_CPUID_SUPPORTED if (z7_x86_cpuid_GetMaxFunc())
|
UInt32 b;
|
||||||
#endif
|
UInt32 c;
|
||||||
|
UInt32 d;
|
||||||
|
} Cx86cpuid;
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CPU_FIRM_INTEL,
|
||||||
|
CPU_FIRM_AMD,
|
||||||
|
CPU_FIRM_VIA
|
||||||
|
};
|
||||||
|
|
||||||
|
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
|
||||||
|
|
||||||
|
BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p);
|
||||||
|
int x86cpuid_GetFirm(const Cx86cpuid *p);
|
||||||
|
|
||||||
|
#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
|
||||||
|
#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
|
||||||
|
#define x86cpuid_GetStepping(ver) (ver & 0xF)
|
||||||
|
|
||||||
|
BoolInt CPU_Is_InOrder(void);
|
||||||
|
|
||||||
BoolInt CPU_IsSupported_AES(void);
|
BoolInt CPU_IsSupported_AES(void);
|
||||||
BoolInt CPU_IsSupported_AVX(void);
|
|
||||||
BoolInt CPU_IsSupported_AVX2(void);
|
BoolInt CPU_IsSupported_AVX2(void);
|
||||||
BoolInt CPU_IsSupported_AVX512F_AVX512VL(void);
|
|
||||||
BoolInt CPU_IsSupported_VAES_AVX2(void);
|
BoolInt CPU_IsSupported_VAES_AVX2(void);
|
||||||
BoolInt CPU_IsSupported_CMOV(void);
|
|
||||||
BoolInt CPU_IsSupported_SSE(void);
|
|
||||||
BoolInt CPU_IsSupported_SSE2(void);
|
|
||||||
BoolInt CPU_IsSupported_SSSE3(void);
|
BoolInt CPU_IsSupported_SSSE3(void);
|
||||||
BoolInt CPU_IsSupported_SSE41(void);
|
BoolInt CPU_IsSupported_SSE41(void);
|
||||||
BoolInt CPU_IsSupported_SHA(void);
|
BoolInt CPU_IsSupported_SHA(void);
|
||||||
BoolInt CPU_IsSupported_SHA512(void);
|
|
||||||
BoolInt CPU_IsSupported_PageGB(void);
|
BoolInt CPU_IsSupported_PageGB(void);
|
||||||
|
|
||||||
#elif defined(MY_CPU_ARM_OR_ARM64)
|
#elif defined(MY_CPU_ARM_OR_ARM64)
|
||||||
|
@ -664,13 +432,12 @@ BoolInt CPU_IsSupported_SHA1(void);
|
||||||
BoolInt CPU_IsSupported_SHA2(void);
|
BoolInt CPU_IsSupported_SHA2(void);
|
||||||
BoolInt CPU_IsSupported_AES(void);
|
BoolInt CPU_IsSupported_AES(void);
|
||||||
#endif
|
#endif
|
||||||
BoolInt CPU_IsSupported_SHA512(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
int z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize);
|
int My_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize);
|
||||||
int z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val);
|
int My_sysctlbyname_Get_UInt32(const char *name, UInt32 *val);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,8 @@
|
||||||
/* LzFind.h -- Match finder for LZ algorithms
|
/* LzFind.h -- Match finder for LZ algorithms
|
||||||
2024-01-22 : Igor Pavlov : Public domain */
|
2021-07-13 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_INC_LZ_FIND_H
|
#ifndef __LZ_FIND_H
|
||||||
#define ZIP7_INC_LZ_FIND_H
|
#define __LZ_FIND_H
|
||||||
|
|
||||||
#include "7zTypes.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
@ -10,9 +10,9 @@ EXTERN_C_BEGIN
|
||||||
|
|
||||||
typedef UInt32 CLzRef;
|
typedef UInt32 CLzRef;
|
||||||
|
|
||||||
typedef struct
|
typedef struct _CMatchFinder
|
||||||
{
|
{
|
||||||
const Byte *buffer;
|
Byte *buffer;
|
||||||
UInt32 pos;
|
UInt32 pos;
|
||||||
UInt32 posLimit;
|
UInt32 posLimit;
|
||||||
UInt32 streamPos; /* wrap over Zero is allowed (streamPos < pos). Use (UInt32)(streamPos - pos) */
|
UInt32 streamPos; /* wrap over Zero is allowed (streamPos < pos). Use (UInt32)(streamPos - pos) */
|
||||||
|
@ -32,8 +32,8 @@ typedef struct
|
||||||
UInt32 hashMask;
|
UInt32 hashMask;
|
||||||
UInt32 cutValue;
|
UInt32 cutValue;
|
||||||
|
|
||||||
Byte *bufBase;
|
Byte *bufferBase;
|
||||||
ISeqInStreamPtr stream;
|
ISeqInStream *stream;
|
||||||
|
|
||||||
UInt32 blockSize;
|
UInt32 blockSize;
|
||||||
UInt32 keepSizeBefore;
|
UInt32 keepSizeBefore;
|
||||||
|
@ -43,9 +43,7 @@ typedef struct
|
||||||
size_t directInputRem;
|
size_t directInputRem;
|
||||||
UInt32 historySize;
|
UInt32 historySize;
|
||||||
UInt32 fixedHashSize;
|
UInt32 fixedHashSize;
|
||||||
Byte numHashBytes_Min;
|
UInt32 hashSizeSum;
|
||||||
Byte numHashOutBits;
|
|
||||||
Byte _pad2_[2];
|
|
||||||
SRes result;
|
SRes result;
|
||||||
UInt32 crc[256];
|
UInt32 crc[256];
|
||||||
size_t numRefs;
|
size_t numRefs;
|
||||||
|
@ -71,45 +69,24 @@ void MatchFinder_ReadIfRequired(CMatchFinder *p);
|
||||||
|
|
||||||
void MatchFinder_Construct(CMatchFinder *p);
|
void MatchFinder_Construct(CMatchFinder *p);
|
||||||
|
|
||||||
/* (directInput = 0) is default value.
|
/* Conditions:
|
||||||
It's required to provide correct (directInput) value
|
historySize <= 3 GB
|
||||||
before calling MatchFinder_Create().
|
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
|
||||||
You can set (directInput) by any of the following calls:
|
|
||||||
- MatchFinder_SET_DIRECT_INPUT_BUF()
|
|
||||||
- MatchFinder_SET_STREAM()
|
|
||||||
- MatchFinder_SET_STREAM_MODE()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MatchFinder_SET_DIRECT_INPUT_BUF(p, _src_, _srcLen_) { \
|
|
||||||
(p)->stream = NULL; \
|
|
||||||
(p)->directInput = 1; \
|
|
||||||
(p)->buffer = (_src_); \
|
|
||||||
(p)->directInputRem = (_srcLen_); }
|
|
||||||
|
|
||||||
/*
|
|
||||||
#define MatchFinder_SET_STREAM_MODE(p) { \
|
|
||||||
(p)->directInput = 0; }
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MatchFinder_SET_STREAM(p, _stream_) { \
|
|
||||||
(p)->stream = _stream_; \
|
|
||||||
(p)->directInput = 0; }
|
|
||||||
|
|
||||||
|
|
||||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||||
ISzAllocPtr alloc);
|
ISzAllocPtr alloc);
|
||||||
void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
|
void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
|
||||||
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
|
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
|
||||||
|
// void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define MatchFinder_INIT_POS(p, val) \
|
#define Inline_MatchFinder_InitPos(p, val) \
|
||||||
(p)->pos = (val); \
|
(p)->pos = (val); \
|
||||||
(p)->streamPos = (val);
|
(p)->streamPos = (val);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
#define Inline_MatchFinder_ReduceOffsets(p, subValue) \
|
||||||
#define MatchFinder_REDUCE_OFFSETS(p, subValue) \
|
|
||||||
(p)->pos -= (subValue); \
|
(p)->pos -= (subValue); \
|
||||||
(p)->streamPos -= (subValue);
|
(p)->streamPos -= (subValue);
|
||||||
|
|
||||||
|
@ -130,7 +107,7 @@ typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
|
||||||
typedef UInt32 * (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
typedef UInt32 * (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
||||||
typedef void (*Mf_Skip_Func)(void *object, UInt32);
|
typedef void (*Mf_Skip_Func)(void *object, UInt32);
|
||||||
|
|
||||||
typedef struct
|
typedef struct _IMatchFinder
|
||||||
{
|
{
|
||||||
Mf_Init_Func Init;
|
Mf_Init_Func Init;
|
||||||
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
||||||
|
@ -144,8 +121,7 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder2 *vTable);
|
||||||
void MatchFinder_Init_LowHash(CMatchFinder *p);
|
void MatchFinder_Init_LowHash(CMatchFinder *p);
|
||||||
void MatchFinder_Init_HighHash(CMatchFinder *p);
|
void MatchFinder_Init_HighHash(CMatchFinder *p);
|
||||||
void MatchFinder_Init_4(CMatchFinder *p);
|
void MatchFinder_Init_4(CMatchFinder *p);
|
||||||
// void MatchFinder_Init(CMatchFinder *p);
|
void MatchFinder_Init(CMatchFinder *p);
|
||||||
void MatchFinder_Init(void *p);
|
|
||||||
|
|
||||||
UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||||
UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/* LzHash.h -- HASH constants for LZ algorithms
|
/* LzHash.h -- HASH functions for LZ algorithms
|
||||||
2023-03-05 : Igor Pavlov : Public domain */
|
2019-10-30 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_INC_LZ_HASH_H
|
#ifndef __LZ_HASH_H
|
||||||
#define ZIP7_INC_LZ_HASH_H
|
#define __LZ_HASH_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
(kHash2Size >= (1 << 8)) : Required
|
(kHash2Size >= (1 << 8)) : Required
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* LzmaDec.c -- LZMA Decoder
|
/* LzmaDec.c -- LZMA Decoder
|
||||||
2023-04-07 : Igor Pavlov : Public domain */
|
2021-04-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
@ -8,15 +8,15 @@
|
||||||
/* #include "CpuArch.h" */
|
/* #include "CpuArch.h" */
|
||||||
#include "LzmaDec.h"
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
// #define kNumTopBits 24
|
#define kNumTopBits 24
|
||||||
#define kTopValue ((UInt32)1 << 24)
|
#define kTopValue ((UInt32)1 << kNumTopBits)
|
||||||
|
|
||||||
#define kNumBitModelTotalBits 11
|
#define kNumBitModelTotalBits 11
|
||||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||||
|
|
||||||
#define RC_INIT_SIZE 5
|
#define RC_INIT_SIZE 5
|
||||||
|
|
||||||
#ifndef Z7_LZMA_DEC_OPT
|
#ifndef _LZMA_DEC_OPT
|
||||||
|
|
||||||
#define kNumMoveBits 5
|
#define kNumMoveBits 5
|
||||||
#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
|
#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
|
||||||
|
@ -25,14 +25,14 @@
|
||||||
#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
|
#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
|
||||||
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
|
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
|
||||||
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
|
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
|
||||||
{ UPDATE_0(p) i = (i + i); A0; } else \
|
{ UPDATE_0(p); i = (i + i); A0; } else \
|
||||||
{ UPDATE_1(p) i = (i + i) + 1; A1; }
|
{ UPDATE_1(p); i = (i + i) + 1; A1; }
|
||||||
|
|
||||||
#define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); }
|
#define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); }
|
||||||
|
|
||||||
#define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \
|
#define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \
|
||||||
{ UPDATE_0(p + i) A0; } else \
|
{ UPDATE_0(p + i); A0; } else \
|
||||||
{ UPDATE_1(p + i) A1; }
|
{ UPDATE_1(p + i); A1; }
|
||||||
#define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; )
|
#define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; )
|
||||||
#define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; )
|
#define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; )
|
||||||
#define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; )
|
#define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; )
|
||||||
|
@ -40,19 +40,19 @@
|
||||||
#define TREE_DECODE(probs, limit, i) \
|
#define TREE_DECODE(probs, limit, i) \
|
||||||
{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
|
{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
|
||||||
|
|
||||||
/* #define Z7_LZMA_SIZE_OPT */
|
/* #define _LZMA_SIZE_OPT */
|
||||||
|
|
||||||
#ifdef Z7_LZMA_SIZE_OPT
|
#ifdef _LZMA_SIZE_OPT
|
||||||
#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
|
#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
|
||||||
#else
|
#else
|
||||||
#define TREE_6_DECODE(probs, i) \
|
#define TREE_6_DECODE(probs, i) \
|
||||||
{ i = 1; \
|
{ i = 1; \
|
||||||
TREE_GET_BIT(probs, i) \
|
TREE_GET_BIT(probs, i); \
|
||||||
TREE_GET_BIT(probs, i) \
|
TREE_GET_BIT(probs, i); \
|
||||||
TREE_GET_BIT(probs, i) \
|
TREE_GET_BIT(probs, i); \
|
||||||
TREE_GET_BIT(probs, i) \
|
TREE_GET_BIT(probs, i); \
|
||||||
TREE_GET_BIT(probs, i) \
|
TREE_GET_BIT(probs, i); \
|
||||||
TREE_GET_BIT(probs, i) \
|
TREE_GET_BIT(probs, i); \
|
||||||
i -= 0x40; }
|
i -= 0x40; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -64,25 +64,25 @@
|
||||||
probLit = prob + (offs + bit + symbol); \
|
probLit = prob + (offs + bit + symbol); \
|
||||||
GET_BIT2(probLit, symbol, offs ^= bit; , ;)
|
GET_BIT2(probLit, symbol, offs ^= bit; , ;)
|
||||||
|
|
||||||
#endif // Z7_LZMA_DEC_OPT
|
#endif // _LZMA_DEC_OPT
|
||||||
|
|
||||||
|
|
||||||
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_INPUT_EOF; range <<= 8; code = (code << 8) | (*buf++); }
|
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_INPUT_EOF; range <<= 8; code = (code << 8) | (*buf++); }
|
||||||
|
|
||||||
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)
|
#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound)
|
||||||
#define UPDATE_0_CHECK range = bound;
|
#define UPDATE_0_CHECK range = bound;
|
||||||
#define UPDATE_1_CHECK range -= bound; code -= bound;
|
#define UPDATE_1_CHECK range -= bound; code -= bound;
|
||||||
#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
|
#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
|
||||||
{ UPDATE_0_CHECK i = (i + i); A0; } else \
|
{ UPDATE_0_CHECK; i = (i + i); A0; } else \
|
||||||
{ UPDATE_1_CHECK i = (i + i) + 1; A1; }
|
{ UPDATE_1_CHECK; i = (i + i) + 1; A1; }
|
||||||
#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
|
#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
|
||||||
#define TREE_DECODE_CHECK(probs, limit, i) \
|
#define TREE_DECODE_CHECK(probs, limit, i) \
|
||||||
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
|
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
|
||||||
|
|
||||||
|
|
||||||
#define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \
|
#define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \
|
||||||
{ UPDATE_0_CHECK i += m; m += m; } else \
|
{ UPDATE_0_CHECK; i += m; m += m; } else \
|
||||||
{ UPDATE_1_CHECK m += m; i += m; }
|
{ UPDATE_1_CHECK; m += m; i += m; }
|
||||||
|
|
||||||
|
|
||||||
#define kNumPosBitsMax 4
|
#define kNumPosBitsMax 4
|
||||||
|
@ -224,14 +224,14 @@ Out:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifdef Z7_LZMA_DEC_OPT
|
#ifdef _LZMA_DEC_OPT
|
||||||
|
|
||||||
int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit);
|
int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static
|
static
|
||||||
int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
{
|
{
|
||||||
CLzmaProb *probs = GET_PROBS;
|
CLzmaProb *probs = GET_PROBS;
|
||||||
unsigned state = (unsigned)p->state;
|
unsigned state = (unsigned)p->state;
|
||||||
|
@ -263,7 +263,7 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
IF_BIT_0(prob)
|
IF_BIT_0(prob)
|
||||||
{
|
{
|
||||||
unsigned symbol;
|
unsigned symbol;
|
||||||
UPDATE_0(prob)
|
UPDATE_0(prob);
|
||||||
prob = probs + Literal;
|
prob = probs + Literal;
|
||||||
if (processedPos != 0 || checkDicSize != 0)
|
if (processedPos != 0 || checkDicSize != 0)
|
||||||
prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc);
|
prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc);
|
||||||
|
@ -273,7 +273,7 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
{
|
{
|
||||||
state -= (state < 4) ? state : 3;
|
state -= (state < 4) ? state : 3;
|
||||||
symbol = 1;
|
symbol = 1;
|
||||||
#ifdef Z7_LZMA_SIZE_OPT
|
#ifdef _LZMA_SIZE_OPT
|
||||||
do { NORMAL_LITER_DEC } while (symbol < 0x100);
|
do { NORMAL_LITER_DEC } while (symbol < 0x100);
|
||||||
#else
|
#else
|
||||||
NORMAL_LITER_DEC
|
NORMAL_LITER_DEC
|
||||||
|
@ -292,7 +292,7 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
unsigned offs = 0x100;
|
unsigned offs = 0x100;
|
||||||
state -= (state < 10) ? 3 : 6;
|
state -= (state < 10) ? 3 : 6;
|
||||||
symbol = 1;
|
symbol = 1;
|
||||||
#ifdef Z7_LZMA_SIZE_OPT
|
#ifdef _LZMA_SIZE_OPT
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
unsigned bit;
|
unsigned bit;
|
||||||
|
@ -321,25 +321,25 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
UPDATE_1(prob)
|
UPDATE_1(prob);
|
||||||
prob = probs + IsRep + state;
|
prob = probs + IsRep + state;
|
||||||
IF_BIT_0(prob)
|
IF_BIT_0(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0(prob)
|
UPDATE_0(prob);
|
||||||
state += kNumStates;
|
state += kNumStates;
|
||||||
prob = probs + LenCoder;
|
prob = probs + LenCoder;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(prob)
|
UPDATE_1(prob);
|
||||||
prob = probs + IsRepG0 + state;
|
prob = probs + IsRepG0 + state;
|
||||||
IF_BIT_0(prob)
|
IF_BIT_0(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0(prob)
|
UPDATE_0(prob);
|
||||||
prob = probs + IsRep0Long + COMBINED_PS_STATE;
|
prob = probs + IsRep0Long + COMBINED_PS_STATE;
|
||||||
IF_BIT_0(prob)
|
IF_BIT_0(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0(prob)
|
UPDATE_0(prob);
|
||||||
|
|
||||||
// that case was checked before with kBadRepCode
|
// that case was checked before with kBadRepCode
|
||||||
// if (checkDicSize == 0 && processedPos == 0) { len = kMatchSpecLen_Error_Data + 1; break; }
|
// if (checkDicSize == 0 && processedPos == 0) { len = kMatchSpecLen_Error_Data + 1; break; }
|
||||||
|
@ -353,30 +353,30 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
state = state < kNumLitStates ? 9 : 11;
|
state = state < kNumLitStates ? 9 : 11;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
UPDATE_1(prob)
|
UPDATE_1(prob);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt32 distance;
|
UInt32 distance;
|
||||||
UPDATE_1(prob)
|
UPDATE_1(prob);
|
||||||
prob = probs + IsRepG1 + state;
|
prob = probs + IsRepG1 + state;
|
||||||
IF_BIT_0(prob)
|
IF_BIT_0(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0(prob)
|
UPDATE_0(prob);
|
||||||
distance = rep1;
|
distance = rep1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(prob)
|
UPDATE_1(prob);
|
||||||
prob = probs + IsRepG2 + state;
|
prob = probs + IsRepG2 + state;
|
||||||
IF_BIT_0(prob)
|
IF_BIT_0(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0(prob)
|
UPDATE_0(prob);
|
||||||
distance = rep2;
|
distance = rep2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(prob)
|
UPDATE_1(prob);
|
||||||
distance = rep3;
|
distance = rep3;
|
||||||
rep3 = rep2;
|
rep3 = rep2;
|
||||||
}
|
}
|
||||||
|
@ -389,37 +389,37 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
prob = probs + RepLenCoder;
|
prob = probs + RepLenCoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Z7_LZMA_SIZE_OPT
|
#ifdef _LZMA_SIZE_OPT
|
||||||
{
|
{
|
||||||
unsigned lim, offset;
|
unsigned lim, offset;
|
||||||
CLzmaProb *probLen = prob + LenChoice;
|
CLzmaProb *probLen = prob + LenChoice;
|
||||||
IF_BIT_0(probLen)
|
IF_BIT_0(probLen)
|
||||||
{
|
{
|
||||||
UPDATE_0(probLen)
|
UPDATE_0(probLen);
|
||||||
probLen = prob + LenLow + GET_LEN_STATE;
|
probLen = prob + LenLow + GET_LEN_STATE;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
lim = (1 << kLenNumLowBits);
|
lim = (1 << kLenNumLowBits);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(probLen)
|
UPDATE_1(probLen);
|
||||||
probLen = prob + LenChoice2;
|
probLen = prob + LenChoice2;
|
||||||
IF_BIT_0(probLen)
|
IF_BIT_0(probLen)
|
||||||
{
|
{
|
||||||
UPDATE_0(probLen)
|
UPDATE_0(probLen);
|
||||||
probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
|
probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
|
||||||
offset = kLenNumLowSymbols;
|
offset = kLenNumLowSymbols;
|
||||||
lim = (1 << kLenNumLowBits);
|
lim = (1 << kLenNumLowBits);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(probLen)
|
UPDATE_1(probLen);
|
||||||
probLen = prob + LenHigh;
|
probLen = prob + LenHigh;
|
||||||
offset = kLenNumLowSymbols * 2;
|
offset = kLenNumLowSymbols * 2;
|
||||||
lim = (1 << kLenNumHighBits);
|
lim = (1 << kLenNumHighBits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TREE_DECODE(probLen, lim, len)
|
TREE_DECODE(probLen, lim, len);
|
||||||
len += offset;
|
len += offset;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -427,32 +427,32 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
CLzmaProb *probLen = prob + LenChoice;
|
CLzmaProb *probLen = prob + LenChoice;
|
||||||
IF_BIT_0(probLen)
|
IF_BIT_0(probLen)
|
||||||
{
|
{
|
||||||
UPDATE_0(probLen)
|
UPDATE_0(probLen);
|
||||||
probLen = prob + LenLow + GET_LEN_STATE;
|
probLen = prob + LenLow + GET_LEN_STATE;
|
||||||
len = 1;
|
len = 1;
|
||||||
TREE_GET_BIT(probLen, len)
|
TREE_GET_BIT(probLen, len);
|
||||||
TREE_GET_BIT(probLen, len)
|
TREE_GET_BIT(probLen, len);
|
||||||
TREE_GET_BIT(probLen, len)
|
TREE_GET_BIT(probLen, len);
|
||||||
len -= 8;
|
len -= 8;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(probLen)
|
UPDATE_1(probLen);
|
||||||
probLen = prob + LenChoice2;
|
probLen = prob + LenChoice2;
|
||||||
IF_BIT_0(probLen)
|
IF_BIT_0(probLen)
|
||||||
{
|
{
|
||||||
UPDATE_0(probLen)
|
UPDATE_0(probLen);
|
||||||
probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
|
probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
|
||||||
len = 1;
|
len = 1;
|
||||||
TREE_GET_BIT(probLen, len)
|
TREE_GET_BIT(probLen, len);
|
||||||
TREE_GET_BIT(probLen, len)
|
TREE_GET_BIT(probLen, len);
|
||||||
TREE_GET_BIT(probLen, len)
|
TREE_GET_BIT(probLen, len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(probLen)
|
UPDATE_1(probLen);
|
||||||
probLen = prob + LenHigh;
|
probLen = prob + LenHigh;
|
||||||
TREE_DECODE(probLen, (1 << kLenNumHighBits), len)
|
TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
|
||||||
len += kLenNumLowSymbols * 2;
|
len += kLenNumLowSymbols * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,7 +464,7 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
UInt32 distance;
|
UInt32 distance;
|
||||||
prob = probs + PosSlot +
|
prob = probs + PosSlot +
|
||||||
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
|
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
|
||||||
TREE_6_DECODE(prob, distance)
|
TREE_6_DECODE(prob, distance);
|
||||||
if (distance >= kStartPosModelIndex)
|
if (distance >= kStartPosModelIndex)
|
||||||
{
|
{
|
||||||
unsigned posSlot = (unsigned)distance;
|
unsigned posSlot = (unsigned)distance;
|
||||||
|
@ -479,7 +479,7 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
distance++;
|
distance++;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
REV_BIT_VAR(prob, distance, m)
|
REV_BIT_VAR(prob, distance, m);
|
||||||
}
|
}
|
||||||
while (--numDirectBits);
|
while (--numDirectBits);
|
||||||
distance -= m;
|
distance -= m;
|
||||||
|
@ -514,10 +514,10 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
distance <<= kNumAlignBits;
|
distance <<= kNumAlignBits;
|
||||||
{
|
{
|
||||||
unsigned i = 1;
|
unsigned i = 1;
|
||||||
REV_BIT_CONST(prob, i, 1)
|
REV_BIT_CONST(prob, i, 1);
|
||||||
REV_BIT_CONST(prob, i, 2)
|
REV_BIT_CONST(prob, i, 2);
|
||||||
REV_BIT_CONST(prob, i, 4)
|
REV_BIT_CONST(prob, i, 4);
|
||||||
REV_BIT_LAST (prob, i, 8)
|
REV_BIT_LAST (prob, i, 8);
|
||||||
distance |= i;
|
distance |= i;
|
||||||
}
|
}
|
||||||
if (distance == (UInt32)0xFFFFFFFF)
|
if (distance == (UInt32)0xFFFFFFFF)
|
||||||
|
@ -592,7 +592,7 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
}
|
}
|
||||||
while (dicPos < limit && buf < bufLimit);
|
while (dicPos < limit && buf < bufLimit);
|
||||||
|
|
||||||
NORMALIZE
|
NORMALIZE;
|
||||||
|
|
||||||
p->buf = buf;
|
p->buf = buf;
|
||||||
p->range = range;
|
p->range = range;
|
||||||
|
@ -613,7 +613,7 @@ int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void Z7_FASTCALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
||||||
{
|
{
|
||||||
unsigned len = (unsigned)p->remainLen;
|
unsigned len = (unsigned)p->remainLen;
|
||||||
if (len == 0 /* || len >= kMatchSpecLenStart */)
|
if (len == 0 /* || len >= kMatchSpecLenStart */)
|
||||||
|
@ -683,7 +683,7 @@ and we support the following state of (p->checkDicSize):
|
||||||
(p->checkDicSize == p->prop.dicSize)
|
(p->checkDicSize == p->prop.dicSize)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int Z7_FASTCALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
||||||
{
|
{
|
||||||
if (p->checkDicSize == 0)
|
if (p->checkDicSize == 0)
|
||||||
{
|
{
|
||||||
|
@ -767,54 +767,54 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byt
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned len;
|
unsigned len;
|
||||||
UPDATE_1_CHECK
|
UPDATE_1_CHECK;
|
||||||
|
|
||||||
prob = probs + IsRep + state;
|
prob = probs + IsRep + state;
|
||||||
IF_BIT_0_CHECK(prob)
|
IF_BIT_0_CHECK(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0_CHECK
|
UPDATE_0_CHECK;
|
||||||
state = 0;
|
state = 0;
|
||||||
prob = probs + LenCoder;
|
prob = probs + LenCoder;
|
||||||
res = DUMMY_MATCH;
|
res = DUMMY_MATCH;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1_CHECK
|
UPDATE_1_CHECK;
|
||||||
res = DUMMY_REP;
|
res = DUMMY_REP;
|
||||||
prob = probs + IsRepG0 + state;
|
prob = probs + IsRepG0 + state;
|
||||||
IF_BIT_0_CHECK(prob)
|
IF_BIT_0_CHECK(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0_CHECK
|
UPDATE_0_CHECK;
|
||||||
prob = probs + IsRep0Long + COMBINED_PS_STATE;
|
prob = probs + IsRep0Long + COMBINED_PS_STATE;
|
||||||
IF_BIT_0_CHECK(prob)
|
IF_BIT_0_CHECK(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0_CHECK
|
UPDATE_0_CHECK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1_CHECK
|
UPDATE_1_CHECK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1_CHECK
|
UPDATE_1_CHECK;
|
||||||
prob = probs + IsRepG1 + state;
|
prob = probs + IsRepG1 + state;
|
||||||
IF_BIT_0_CHECK(prob)
|
IF_BIT_0_CHECK(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0_CHECK
|
UPDATE_0_CHECK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1_CHECK
|
UPDATE_1_CHECK;
|
||||||
prob = probs + IsRepG2 + state;
|
prob = probs + IsRepG2 + state;
|
||||||
IF_BIT_0_CHECK(prob)
|
IF_BIT_0_CHECK(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0_CHECK
|
UPDATE_0_CHECK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1_CHECK
|
UPDATE_1_CHECK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -826,31 +826,31 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byt
|
||||||
const CLzmaProb *probLen = prob + LenChoice;
|
const CLzmaProb *probLen = prob + LenChoice;
|
||||||
IF_BIT_0_CHECK(probLen)
|
IF_BIT_0_CHECK(probLen)
|
||||||
{
|
{
|
||||||
UPDATE_0_CHECK
|
UPDATE_0_CHECK;
|
||||||
probLen = prob + LenLow + GET_LEN_STATE;
|
probLen = prob + LenLow + GET_LEN_STATE;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
limit = 1 << kLenNumLowBits;
|
limit = 1 << kLenNumLowBits;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1_CHECK
|
UPDATE_1_CHECK;
|
||||||
probLen = prob + LenChoice2;
|
probLen = prob + LenChoice2;
|
||||||
IF_BIT_0_CHECK(probLen)
|
IF_BIT_0_CHECK(probLen)
|
||||||
{
|
{
|
||||||
UPDATE_0_CHECK
|
UPDATE_0_CHECK;
|
||||||
probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
|
probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
|
||||||
offset = kLenNumLowSymbols;
|
offset = kLenNumLowSymbols;
|
||||||
limit = 1 << kLenNumLowBits;
|
limit = 1 << kLenNumLowBits;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1_CHECK
|
UPDATE_1_CHECK;
|
||||||
probLen = prob + LenHigh;
|
probLen = prob + LenHigh;
|
||||||
offset = kLenNumLowSymbols * 2;
|
offset = kLenNumLowSymbols * 2;
|
||||||
limit = 1 << kLenNumHighBits;
|
limit = 1 << kLenNumHighBits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TREE_DECODE_CHECK(probLen, limit, len)
|
TREE_DECODE_CHECK(probLen, limit, len);
|
||||||
len += offset;
|
len += offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -860,7 +860,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byt
|
||||||
prob = probs + PosSlot +
|
prob = probs + PosSlot +
|
||||||
((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) <<
|
((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) <<
|
||||||
kNumPosSlotBits);
|
kNumPosSlotBits);
|
||||||
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot)
|
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
|
||||||
if (posSlot >= kStartPosModelIndex)
|
if (posSlot >= kStartPosModelIndex)
|
||||||
{
|
{
|
||||||
unsigned numDirectBits = ((posSlot >> 1) - 1);
|
unsigned numDirectBits = ((posSlot >> 1) - 1);
|
||||||
|
@ -888,7 +888,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byt
|
||||||
unsigned m = 1;
|
unsigned m = 1;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
REV_BIT_CHECK(prob, i, m)
|
REV_BIT_CHECK(prob, i, m);
|
||||||
}
|
}
|
||||||
while (--numDirectBits);
|
while (--numDirectBits);
|
||||||
}
|
}
|
||||||
|
@ -897,7 +897,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byt
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
NORMALIZE_CHECK
|
NORMALIZE_CHECK;
|
||||||
|
|
||||||
*bufOut = buf;
|
*bufOut = buf;
|
||||||
return res;
|
return res;
|
||||||
|
@ -943,7 +943,7 @@ When the decoder lookahead, and the lookahead symbol is not end_marker, we have
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define RETURN_NOT_FINISHED_FOR_FINISH \
|
#define RETURN__NOT_FINISHED__FOR_FINISH \
|
||||||
*status = LZMA_STATUS_NOT_FINISHED; \
|
*status = LZMA_STATUS_NOT_FINISHED; \
|
||||||
return SZ_ERROR_DATA; // for strict mode
|
return SZ_ERROR_DATA; // for strict mode
|
||||||
// return SZ_OK; // for relaxed mode
|
// return SZ_OK; // for relaxed mode
|
||||||
|
@ -1029,7 +1029,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
||||||
}
|
}
|
||||||
if (p->remainLen != 0)
|
if (p->remainLen != 0)
|
||||||
{
|
{
|
||||||
RETURN_NOT_FINISHED_FOR_FINISH
|
RETURN__NOT_FINISHED__FOR_FINISH;
|
||||||
}
|
}
|
||||||
checkEndMarkNow = 1;
|
checkEndMarkNow = 1;
|
||||||
}
|
}
|
||||||
|
@ -1072,7 +1072,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
||||||
for (i = 0; i < (unsigned)dummyProcessed; i++)
|
for (i = 0; i < (unsigned)dummyProcessed; i++)
|
||||||
p->tempBuf[i] = src[i];
|
p->tempBuf[i] = src[i];
|
||||||
// p->remainLen = kMatchSpecLen_Error_Data;
|
// p->remainLen = kMatchSpecLen_Error_Data;
|
||||||
RETURN_NOT_FINISHED_FOR_FINISH
|
RETURN__NOT_FINISHED__FOR_FINISH;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufLimit = src;
|
bufLimit = src;
|
||||||
|
@ -1150,7 +1150,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
||||||
(*srcLen) += (unsigned)dummyProcessed - p->tempBufSize;
|
(*srcLen) += (unsigned)dummyProcessed - p->tempBufSize;
|
||||||
p->tempBufSize = (unsigned)dummyProcessed;
|
p->tempBufSize = (unsigned)dummyProcessed;
|
||||||
// p->remainLen = kMatchSpecLen_Error_Data;
|
// p->remainLen = kMatchSpecLen_Error_Data;
|
||||||
RETURN_NOT_FINISHED_FOR_FINISH
|
RETURN__NOT_FINISHED__FOR_FINISH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1299,8 +1299,8 @@ static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAl
|
||||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
|
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CLzmaProps propNew;
|
CLzmaProps propNew;
|
||||||
RINOK(LzmaProps_Decode(&propNew, props, propsSize))
|
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
||||||
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc))
|
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
|
||||||
p->prop = propNew;
|
p->prop = propNew;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
@ -1309,14 +1309,14 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
|
||||||
{
|
{
|
||||||
CLzmaProps propNew;
|
CLzmaProps propNew;
|
||||||
SizeT dicBufSize;
|
SizeT dicBufSize;
|
||||||
RINOK(LzmaProps_Decode(&propNew, props, propsSize))
|
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
||||||
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc))
|
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt32 dictSize = propNew.dicSize;
|
UInt32 dictSize = propNew.dicSize;
|
||||||
SizeT mask = ((UInt32)1 << 12) - 1;
|
SizeT mask = ((UInt32)1 << 12) - 1;
|
||||||
if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;
|
if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;
|
||||||
else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;
|
else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;;
|
||||||
dicBufSize = ((SizeT)dictSize + mask) & ~mask;
|
dicBufSize = ((SizeT)dictSize + mask) & ~mask;
|
||||||
if (dicBufSize < dictSize)
|
if (dicBufSize < dictSize)
|
||||||
dicBufSize = dictSize;
|
dicBufSize = dictSize;
|
||||||
|
@ -1348,8 +1348,8 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
if (inSize < RC_INIT_SIZE)
|
if (inSize < RC_INIT_SIZE)
|
||||||
return SZ_ERROR_INPUT_EOF;
|
return SZ_ERROR_INPUT_EOF;
|
||||||
LzmaDec_CONSTRUCT(&p)
|
LzmaDec_Construct(&p);
|
||||||
RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc))
|
RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc));
|
||||||
p.dic = dest;
|
p.dic = dest;
|
||||||
p.dicBufSize = outSize;
|
p.dicBufSize = outSize;
|
||||||
LzmaDec_Init(&p);
|
LzmaDec_Init(&p);
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
/* LzmaDec.h -- LZMA Decoder
|
/* LzmaDec.h -- LZMA Decoder
|
||||||
2023-04-02 : Igor Pavlov : Public domain */
|
2020-03-19 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_INC_LZMA_DEC_H
|
#ifndef __LZMA_DEC_H
|
||||||
#define ZIP7_INC_LZMA_DEC_H
|
#define __LZMA_DEC_H
|
||||||
|
|
||||||
#include "7zTypes.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
EXTERN_C_BEGIN
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
/* #define Z7_LZMA_PROB32 */
|
/* #define _LZMA_PROB32 */
|
||||||
/* Z7_LZMA_PROB32 can increase the speed on some CPUs,
|
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||||
but memory usage for CLzmaDec::probs will be doubled in that case */
|
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
#ifdef Z7_LZMA_PROB32
|
#ifdef _LZMA_PROB32
|
||||||
UInt32
|
UInt32
|
||||||
#else
|
#else
|
||||||
UInt16
|
UInt16
|
||||||
|
@ -25,7 +25,7 @@ typedef
|
||||||
|
|
||||||
#define LZMA_PROPS_SIZE 5
|
#define LZMA_PROPS_SIZE 5
|
||||||
|
|
||||||
typedef struct
|
typedef struct _CLzmaProps
|
||||||
{
|
{
|
||||||
Byte lc;
|
Byte lc;
|
||||||
Byte lp;
|
Byte lp;
|
||||||
|
@ -73,8 +73,7 @@ typedef struct
|
||||||
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||||
} CLzmaDec;
|
} CLzmaDec;
|
||||||
|
|
||||||
#define LzmaDec_CONSTRUCT(p) { (p)->dic = NULL; (p)->probs = NULL; }
|
#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; }
|
||||||
#define LzmaDec_Construct(p) LzmaDec_CONSTRUCT(p)
|
|
||||||
|
|
||||||
void LzmaDec_Init(CLzmaDec *p);
|
void LzmaDec_Init(CLzmaDec *p);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,8 @@
|
||||||
/* LzmaEnc.h -- LZMA Encoder
|
/* LzmaEnc.h -- LZMA Encoder
|
||||||
2023-04-13 : Igor Pavlov : Public domain */
|
2019-10-30 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_INC_LZMA_ENC_H
|
#ifndef __LZMA_ENC_H
|
||||||
#define ZIP7_INC_LZMA_ENC_H
|
#define __LZMA_ENC_H
|
||||||
|
|
||||||
#include "7zTypes.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ EXTERN_C_BEGIN
|
||||||
|
|
||||||
#define LZMA_PROPS_SIZE 5
|
#define LZMA_PROPS_SIZE 5
|
||||||
|
|
||||||
typedef struct
|
typedef struct _CLzmaEncProps
|
||||||
{
|
{
|
||||||
int level; /* 0 <= level <= 9 */
|
int level; /* 0 <= level <= 9 */
|
||||||
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
||||||
|
@ -23,13 +23,10 @@ typedef struct
|
||||||
int fb; /* 5 <= fb <= 273, default = 32 */
|
int fb; /* 5 <= fb <= 273, default = 32 */
|
||||||
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
||||||
int numHashBytes; /* 2, 3 or 4, default = 4 */
|
int numHashBytes; /* 2, 3 or 4, default = 4 */
|
||||||
unsigned numHashOutBits; /* default = ? */
|
|
||||||
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
|
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
|
||||||
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
|
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
|
||||||
int numThreads; /* 1 or 2, default = 2 */
|
int numThreads; /* 1 or 2, default = 2 */
|
||||||
|
|
||||||
// int _pad;
|
|
||||||
|
|
||||||
UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.
|
UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.
|
||||||
Encoder uses this value to reduce dictionary size */
|
Encoder uses this value to reduce dictionary size */
|
||||||
|
|
||||||
|
@ -54,9 +51,7 @@ SRes:
|
||||||
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
|
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct CLzmaEnc CLzmaEnc;
|
typedef void * CLzmaEncHandle;
|
||||||
typedef CLzmaEnc * CLzmaEncHandle;
|
|
||||||
// Z7_DECLARE_HANDLE(CLzmaEncHandle)
|
|
||||||
|
|
||||||
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
|
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
|
||||||
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
|
@ -66,17 +61,17 @@ void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize);
|
||||||
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
||||||
unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
|
unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
|
||||||
|
|
||||||
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream,
|
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
|
|
||||||
|
|
||||||
/* ---------- One Call Interface ---------- */
|
/* ---------- One Call Interface ---------- */
|
||||||
|
|
||||||
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||||
ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
|
|
@ -1,130 +1,12 @@
|
||||||
/* Precomp.h -- precompilation file
|
/* Precomp.h -- StdAfx
|
||||||
2024-01-25 : Igor Pavlov : Public domain */
|
2013-11-12 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef ZIP7_INC_PRECOMP_H
|
#ifndef __7Z_PRECOMP_H
|
||||||
#define ZIP7_INC_PRECOMP_H
|
#define __7Z_PRECOMP_H
|
||||||
|
|
||||||
/*
|
|
||||||
this file must be included before another *.h files and before <windows.h>.
|
|
||||||
this file is included from the following files:
|
|
||||||
C\*.c
|
|
||||||
C\Util\*\Precomp.h <- C\Util\*\*.c
|
|
||||||
CPP\Common\Common.h <- *\StdAfx.h <- *\*.cpp
|
|
||||||
|
|
||||||
this file can set the following macros:
|
|
||||||
Z7_LARGE_PAGES 1
|
|
||||||
Z7_LONG_PATH 1
|
|
||||||
Z7_WIN32_WINNT_MIN 0x0500 (or higher) : we require at least win2000+ for 7-Zip
|
|
||||||
_WIN32_WINNT 0x0500 (or higher)
|
|
||||||
WINVER _WIN32_WINNT
|
|
||||||
UNICODE 1
|
|
||||||
_UNICODE 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
/* #include "7zTypes.h" */
|
||||||
|
|
||||||
// UEFITool: use single-threaded LzFind
|
#define _7ZIP_ST
|
||||||
#define Z7_ST
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
// #pragma warning(disable : 4206) // nonstandard extension used : translation unit is empty
|
|
||||||
#if _MSC_VER >= 1912
|
|
||||||
// #pragma warning(disable : 5039) // pointer or reference to potentially throwing function passed to 'extern "C"' function under - EHc.Undefined behavior may occur if this function throws an exception.
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
// for debug:
|
|
||||||
#define UNICODE 1
|
|
||||||
#define _UNICODE 1
|
|
||||||
#define _WIN32_WINNT 0x0500 // win2000
|
|
||||||
#ifndef WINVER
|
|
||||||
#define WINVER _WIN32_WINNT
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
/*
|
|
||||||
this "Precomp.h" file must be included before <windows.h>,
|
|
||||||
if we want to define _WIN32_WINNT before <windows.h>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Z7_LARGE_PAGES
|
|
||||||
#ifndef Z7_NO_LARGE_PAGES
|
|
||||||
#define Z7_LARGE_PAGES 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Z7_LONG_PATH
|
|
||||||
#ifndef Z7_NO_LONG_PATH
|
|
||||||
#define Z7_LONG_PATH 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Z7_DEVICE_FILE
|
|
||||||
#ifndef Z7_NO_DEVICE_FILE
|
|
||||||
// #define Z7_DEVICE_FILE 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// we don't change macros if included after <windows.h>
|
|
||||||
#ifndef _WINDOWS_
|
|
||||||
|
|
||||||
#ifndef Z7_WIN32_WINNT_MIN
|
|
||||||
#if defined(_M_ARM64) || defined(__aarch64__)
|
|
||||||
// #define Z7_WIN32_WINNT_MIN 0x0a00 // win10
|
|
||||||
#define Z7_WIN32_WINNT_MIN 0x0600 // vista
|
|
||||||
#elif defined(_M_ARM) && defined(_M_ARMT) && defined(_M_ARM_NT)
|
|
||||||
// #define Z7_WIN32_WINNT_MIN 0x0602 // win8
|
|
||||||
#define Z7_WIN32_WINNT_MIN 0x0600 // vista
|
|
||||||
#elif defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_M_IA64)
|
|
||||||
#define Z7_WIN32_WINNT_MIN 0x0503 // win2003
|
|
||||||
// #elif defined(_M_IX86) || defined(__i386__)
|
|
||||||
// #define Z7_WIN32_WINNT_MIN 0x0500 // win2000
|
|
||||||
#else // x86 and another(old) systems
|
|
||||||
#define Z7_WIN32_WINNT_MIN 0x0500 // win2000
|
|
||||||
// #define Z7_WIN32_WINNT_MIN 0x0502 // win2003 // for debug
|
|
||||||
#endif
|
|
||||||
#endif // Z7_WIN32_WINNT_MIN
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef Z7_DO_NOT_DEFINE_WIN32_WINNT
|
|
||||||
#ifdef _WIN32_WINNT
|
|
||||||
// #error Stop_Compiling_Bad_WIN32_WINNT
|
|
||||||
#else
|
|
||||||
#ifndef Z7_NO_DEFINE_WIN32_WINNT
|
|
||||||
Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
|
|
||||||
#define _WIN32_WINNT Z7_WIN32_WINNT_MIN
|
|
||||||
Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
|
|
||||||
#endif
|
|
||||||
#endif // _WIN32_WINNT
|
|
||||||
|
|
||||||
#ifndef WINVER
|
|
||||||
#define WINVER _WIN32_WINNT
|
|
||||||
#endif
|
|
||||||
#endif // Z7_DO_NOT_DEFINE_WIN32_WINNT
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _MBCS
|
|
||||||
#ifndef Z7_NO_UNICODE
|
|
||||||
// UNICODE and _UNICODE are used by <windows.h> and by 7-zip code.
|
|
||||||
|
|
||||||
#ifndef UNICODE
|
|
||||||
#define UNICODE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _UNICODE
|
|
||||||
Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
|
|
||||||
#define _UNICODE 1
|
|
||||||
Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // Z7_NO_UNICODE
|
|
||||||
#endif // _MBCS
|
|
||||||
#endif // _WINDOWS_
|
|
||||||
|
|
||||||
// #include "7zWindows.h"
|
|
||||||
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
/* RotateDefs.h -- Rotate functions
|
|
||||||
2023-06-18 : Igor Pavlov : Public domain */
|
|
||||||
|
|
||||||
#ifndef ZIP7_INC_ROTATE_DEFS_H
|
|
||||||
#define ZIP7_INC_ROTATE_DEFS_H
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* don't use _rotl with old MINGW. It can insert slow call to function. */
|
|
||||||
|
|
||||||
/* #if (_MSC_VER >= 1200) */
|
|
||||||
#pragma intrinsic(_rotl)
|
|
||||||
#pragma intrinsic(_rotr)
|
|
||||||
/* #endif */
|
|
||||||
|
|
||||||
#define rotlFixed(x, n) _rotl((x), (n))
|
|
||||||
#define rotrFixed(x, n) _rotr((x), (n))
|
|
||||||
|
|
||||||
#if (_MSC_VER >= 1300)
|
|
||||||
#define Z7_ROTL64(x, n) _rotl64((x), (n))
|
|
||||||
#define Z7_ROTR64(x, n) _rotr64((x), (n))
|
|
||||||
#else
|
|
||||||
#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
|
|
||||||
#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* new compilers can translate these macros to fast commands. */
|
|
||||||
|
|
||||||
#if defined(__clang__) && (__clang_major__ >= 4) \
|
|
||||||
|| defined(__GNUC__) && (__GNUC__ >= 5)
|
|
||||||
/* GCC 4.9.0 and clang 3.5 can recognize more correct version: */
|
|
||||||
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (-(n) & 31)))
|
|
||||||
#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (-(n) & 31)))
|
|
||||||
#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (-(n) & 63)))
|
|
||||||
#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (-(n) & 63)))
|
|
||||||
#else
|
|
||||||
/* for old GCC / clang: */
|
|
||||||
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
|
||||||
#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
|
|
||||||
#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
|
|
||||||
#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
31
common/LZMA/UefiLzma.h
Normal file
31
common/LZMA/UefiLzma.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/* LZMA UEFI header file
|
||||||
|
|
||||||
|
Copyright (c) 2009, Intel Corporation. All rights reserved.
|
||||||
|
This program and the accompanying materials
|
||||||
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
http://opensource.org/licenses/bsd-license.php
|
||||||
|
|
||||||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||||
|
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UEFILZMA_H__
|
||||||
|
#define __UEFILZMA_H__
|
||||||
|
|
||||||
|
#include "../basetypes.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#undef _WIN32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#undef _WIN64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _LZMA_SIZE_OPT
|
||||||
|
#define _7ZIP_ST
|
||||||
|
|
||||||
|
#endif // __UEFILZMA_H__
|
||||||
|
|
|
@ -226,4 +226,10 @@ typedef struct EFI_TIME_ {
|
||||||
#define __STDC_FORMAT_MACROS
|
#define __STDC_FORMAT_MACROS
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
|
#define ATTRIBUTE_FORMAT_(t,f,a) __attribute__((format(t, f, a)))
|
||||||
|
#else
|
||||||
|
#define ATTRIBUTE_FORMAT_(t,f,a)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // BASETYPES_H
|
#endif // BASETYPES_H
|
||||||
|
|
|
@ -22,6 +22,7 @@ extern "C" {
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include "../basetypes.h"
|
||||||
|
|
||||||
#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
|
#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
|
||||||
# if defined (__TURBOC__) && !defined (__BORLANDC__)
|
# if defined (__TURBOC__) && !defined (__BORLANDC__)
|
||||||
|
@ -29,12 +30,6 @@ extern "C" {
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__clang__) || defined(__GNUC__)
|
|
||||||
#define ATTRIBUTE_FORMAT_(t,f,a) __attribute__((format(t, f, a)))
|
|
||||||
#else
|
|
||||||
#define ATTRIBUTE_FORMAT_(t,f,a)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BSTR_ERR (-1)
|
#define BSTR_ERR (-1)
|
||||||
#define BSTR_OK (0)
|
#define BSTR_OK (0)
|
||||||
#define BSTR_BS_BUFF_LENGTH_GET (0)
|
#define BSTR_BS_BUFF_LENGTH_GET (0)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue