diff --git a/.github/update_resource_version.py b/.github/update_resource_version.py deleted file mode 100644 index 15a00eb..0000000 --- a/.github/update_resource_version.py +++ /dev/null @@ -1,17 +0,0 @@ -import sys -import json - -if len(sys.argv) < 3: - print("Usage: python update_resource_version.py ") - exit(1) - -properties_file = sys.argv[1] -version = sys.argv[2] - -with open(properties_file, "r") as f: - data = json.load(f) - -data["version"] = version - -with open(properties_file, "w") as f: - json.dump(data, f, indent=4) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index a354ded..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,245 +0,0 @@ -name: build cli - -permissions: - contents: write - -on: - push: - tags: - - 'v*' - branches: - - '**' - paths: - - '.github/workflows/ci.yml' - - 'source/cli/**' - - 'assets/**' - - 'cmake/**' - - 'CMakelists.txt' - - 'CMakePresets.json' - pull_request: - branches: - - '**' - paths: - - '.github/workflows/ci.yml' - - 'source/cli/**' - - 'assets/**' - - 'cmake/**' - - 'CMakelists.txt' - - 'CMakePresets.json' - workflow_dispatch: - -jobs: - meta: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - id: set_tag - run: | - is_release=${{ startsWith(github.ref, 'refs/tags/v') }} - tag=$(git describe --tags --match "v*" ${{ github.ref }} || true) - if [[ $tag != v* ]]; then - tag=$(curl -sX GET "https://api.github.com/repos/MaaAssistantArknights/MaaFramework/releases/latest" --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' | awk '/tag_name/{print $4}' FS='["]') - if [[ $tag != v* ]]; then - tag="v0.0.0" - fi - tag=$(date "+$tag-%y%m%d-$(git rev-parse --short HEAD)") - fi - if ! $($is_release) ; then - prefix=${tag%-*-*} - suffix=${tag#$prefix-} - tag="$prefix-ci.$suffix" - fi - - echo tag=$tag | tee -a $GITHUB_OUTPUT - echo is_release=$is_release | tee -a $GITHUB_OUTPUT - outputs: - tag: ${{ steps.set_tag.outputs.tag }} - is_release: ${{ steps.set_tag.outputs.is_release }} - - windows: - needs: meta - runs-on: windows-latest - strategy: - matrix: - arch: [aarch64, x86_64] - fail-fast: false - - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Update resource version - run: | - python3 .github/update_resource_version.py assets/resource/properties.json ${{ needs.meta.outputs.tag }} - - - name: Download MaaFramework - uses: robinraju/release-downloader@v1.8 - with: - repository: MaaAssistantArknights/MaaFramework - latest: true - fileName: "MAA-win-${{ matrix.arch }}*" - out-file-path: "deps" - extract: true - - - name: Build MAS - run: | - cmake --preset "${{ matrix.arch == 'x86_64' && 'MSVC 2022' || 'MSVC 2022 ARM' }}" -DMAS_HASH_VERSION='${{ needs.meta.outputs.tag }}' - - cmake --build build --config Release -j 16 - - - name: Install - shell: bash - run: | - cmake --install build --prefix install - - - uses: actions/upload-artifact@v3 - with: - name: MAS-win-${{ matrix.arch }} - path: "install" - - ubuntu: - needs: meta - runs-on: ubuntu-latest - container: archlinux:base-devel - strategy: - matrix: - arch: [aarch64, x86_64] - fail-fast: false - - steps: - # maybe should explicitly update some pkg instead of all? - - name: Update system - run: | - pacman -Syu --noconfirm - - - name: Install dep - run: | - pacman -Sy - pacman -S --noconfirm cmake python ccache ninja git - - # https://github.com/MaaAssistantArknights/MaaFramework/actions/runs/5643408179/job/15285186255 - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install cross compile toolchains - if: ${{ matrix.arch != 'x86_64' }} - run: | - pacman -Sy - pacman -S --noconfirm aarch64-linux-gnu-gcc - - - name: Setup ccache - uses: Chocobo1/setup-ccache-action@v1 - with: - remove_stale_cache: false - - - name: Update resource version - run: | - python3 .github/update_resource_version.py assets/resource/properties.json ${{ needs.meta.outputs.tag }} - - - name: Download MaaFramework - uses: robinraju/release-downloader@v1.8 - with: - repository: MaaAssistantArknights/MaaFramework - latest: true - fileName: "MAA-linux-${{ matrix.arch }}*" - out-file-path: "deps" - extract: true - - - name: Build MAS - env: - CC: ${{ matrix.arch == 'x86_64' && 'ccache gcc' || 'ccache aarch64-linux-gnu-gcc' }} - CXX: ${{ matrix.arch == 'x86_64' && 'ccache g++' || 'ccache aarch64-linux-gnu-g++' }} - run: | - cmake --preset 'NinjaMulti' \ - -DMAS_HASH_VERSION='${{ needs.meta.outputs.tag }}' - - cmake --build build --config Release -j 16 - - - name: Install - shell: bash - run: | - cmake --install build --prefix install - - - uses: actions/upload-artifact@v3 - with: - name: MAS-linux-${{ matrix.arch }} - path: "install" - - macos: - needs: meta - runs-on: macos-latest - strategy: - matrix: - arch: [aarch64, x86_64] - fail-fast: false - - steps: - - uses: actions/checkout@v3 - with: - submodules: true - - - name: Install dep - run: | - brew install cmake python ninja - # ccache? - - - name: Install compiler - run: | - brew install llvm - # 16 - - - name: Update resource version - run: | - python3 .github/update_resource_version.py assets/resource/properties.json ${{ needs.meta.outputs.tag }} - - - name: Download MaaFramework - uses: robinraju/release-downloader@v1.8 - with: - repository: MaaAssistantArknights/MaaFramework - latest: true - fileName: "MAA-macos-${{ matrix.arch }}*" - out-file-path: "deps" - extract: true - - - name: Build MAS - env: - CC: "/usr/local/opt/llvm/bin/clang" - CXX: "/usr/local/opt/llvm/bin/clang++" - run: | - cmake --preset 'NinjaMulti' \ - -DARCH='${{ matrix.arch == 'x86_64' && 'x64' || 'arm64' }}' \ - -DMAS_HASH_VERSION='${{ needs.meta.outputs.tag }}' - - cmake --build build --config Release -j 16 - - - name: Install - shell: bash - run: | - cmake --install build --prefix install - - - uses: actions/upload-artifact@v3 - with: - name: MAS-macos-${{ matrix.arch }} - path: "install" - - release: - if: ${{ needs.meta.outputs.is_release == 'true' }} - needs: [meta, windows, ubuntu, macos] - runs-on: ubuntu-latest - steps: - - uses: actions/download-artifact@v3 - with: - path: assets - - run: | - cd assets - for f in *; do - (cd $f && zip -r ../$f-${{ needs.meta.outputs.tag }}.zip .) - done - - uses: softprops/action-gh-release@v1 - with: - files: assets/* - tag_name: ${{ needs.meta.outputs.tag }} \ No newline at end of file diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml new file mode 100644 index 0000000..f3fa9f1 --- /dev/null +++ b/.github/workflows/install.yml @@ -0,0 +1,165 @@ +name: install + +on: + push: + tags: + - "v*" + branches: + - "**" + paths: + - ".github/workflows/install.yml" + - "assets/**" + - "**.py" + pull_request: + branches: + - "**" + paths: + - ".github/workflows/install.yml" + - "assets/**" + - "**.py" + workflow_dispatch: + +jobs: + meta: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - id: set_tag + run: | + is_release=${{ startsWith(github.ref, 'refs/tags/v') }} + tag=$(git describe --tags --match "v*" ${{ github.ref }} || true) + if [[ $tag != v* ]]; then + tag=$(curl -sX GET "https://api.github.com/repos/${{ github.repository }}/releases/latest" --header 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' | awk '/tag_name/{print $4}' FS='["]') + if [[ $tag != v* ]]; then + tag="v0.0.0" + fi + tag=$(date "+$tag-%y%m%d-$(git rev-parse --short HEAD)") + fi + if ! $($is_release) ; then + prefix=${tag%-*-*} + suffix=${tag#$prefix-} + tag="$prefix-ci.$suffix" + fi + + echo tag=$tag | tee -a $GITHUB_OUTPUT + echo is_release=$is_release | tee -a $GITHUB_OUTPUT + outputs: + tag: ${{ steps.set_tag.outputs.tag }} + is_release: ${{ steps.set_tag.outputs.is_release }} + + windows: + needs: meta + runs-on: windows-latest + strategy: + matrix: + arch: [aarch64, x86_64] + fail-fast: false + + steps: + - uses: actions/checkout@v3 + with: + submodules: true + + - name: Download MaaFramework + uses: robinraju/release-downloader@v1.8 + with: + repository: MaaXYZ/MaaFramework + fileName: "MAA-win-${{ matrix.arch }}*" + latest: true + out-file-path: "deps" + extract: true + + - name: Install + shell: bash + run: | + python ./install.py ${{ needs.meta.outputs.tag }} + + - uses: actions/upload-artifact@v3 + with: + name: MAS-win-${{ matrix.arch }} + path: "install" + + ubuntu: + needs: meta + runs-on: ubuntu-latest + strategy: + matrix: + arch: [aarch64, x86_64] + fail-fast: false + + steps: + - uses: actions/checkout@v3 + with: + submodules: true + + - name: Download MaaFramework + uses: robinraju/release-downloader@v1.8 + with: + repository: MaaXYZ/MaaFramework + fileName: "MAA-linux-${{ matrix.arch }}*" + latest: true + out-file-path: "deps" + extract: true + + - name: Install + shell: bash + run: | + python ./install.py ${{ needs.meta.outputs.tag }} + + - uses: actions/upload-artifact@v3 + with: + name: MAS-linux-${{ matrix.arch }} + path: "install" + + macos: + needs: meta + runs-on: macos-latest + strategy: + matrix: + arch: [aarch64, x86_64] + fail-fast: false + + steps: + - uses: actions/checkout@v3 + with: + submodules: true + + - name: Download MaaFramework + uses: robinraju/release-downloader@v1.8 + with: + repository: MaaXYZ/MaaFramework + fileName: "MAA-macos-${{ matrix.arch }}*" + latest: true + out-file-path: "deps" + extract: true + + - name: Install + shell: bash + run: | + python ./install.py ${{ needs.meta.outputs.tag }} + + - uses: actions/upload-artifact@v3 + with: + name: MAS-macos-${{ matrix.arch }} + path: "install" + + release: + if: ${{ needs.meta.outputs.is_release == 'true' }} + needs: [meta, windows, ubuntu, macos] + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v3 + with: + path: assets + + - run: | + cd assets + for f in *; do + (cd $f && zip -r ../$f-${{ needs.meta.outputs.tag }}.zip .) + done + - uses: softprops/action-gh-release@v1 + with: + files: assets/* + tag_name: ${{ needs.meta.outputs.tag }} diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..49b7fbe --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "assets/MaaCommonAssets"] + path = assets/MaaCommonAssets + url = https://github.com/MaaXYZ/MaaCommonAssets.git diff --git a/.maay/control.json b/.maay/control.json deleted file mode 100644 index a8124aa..0000000 --- a/.maay/control.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "option": { - "close": { - "name": "关闭森空岛", - "default": true, - "type": "checkbox", - "inject": ["CloseSkland.enabled"] - } - }, - "entry": [ - { - "name": "森空岛签到", - "task": "Skland", - "option": ["close"] - } - ] -} diff --git a/.maay/repo.json b/.maay/repo.json deleted file mode 100644 index eec7f72..0000000 --- a/.maay/repo.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "resource": { - "default": "assets/resource" - } -} diff --git a/.maay/resource.json b/.maay/resource.json deleted file mode 100644 index 9e970b2..0000000 --- a/.maay/resource.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "resource": { - "default": { - "name": "森空岛", - "path": "@default" - } - }, - "app": { - "start": "com.hypergryph.skland/com.hypergryph.skland.SplashActivity", - "stop": "com.hypergryph.skland", - "orientation": "portrait", - "size": { - "short": 720 - } - } -} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..beea32e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "json.schemas": [ + { + "fileMatch": [ + "/assets/resource/**/*.json", + "/install/resource/**/*.json" + ], + "url": "/deps/tools/pipeline.schema.json" + } + ], + "[json]": { + "editor.formatOnSave": true, + "editor.insertSpaces": true, + "editor.tabSize": 4, + "editor.indentSize": "tabSize" + }, + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter" + } +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 296b5de..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -cmake_minimum_required(VERSION 3.21) -project(MAS) - -set_property(GLOBAL PROPERTY USE_FOLDERS ON) -set(Boost_NO_WARN_NEW_VERSIONS 1) - -include(${PROJECT_SOURCE_DIR}/cmake/config.cmake) # Basic compile & link configuration -include(${PROJECT_SOURCE_DIR}/cmake/assets.cmake) -include(${PROJECT_SOURCE_DIR}/cmake/utils.cmake) -include(${PROJECT_SOURCE_DIR}/cmake/version.cmake) -include(${PROJECT_SOURCE_DIR}/cmake/framework.cmake) - -# if(USE_MAADEPS) -# include(${PROJECT_SOURCE_DIR}/MaaDeps/maadeps.cmake) -# endif() -# find_package(OpenCV REQUIRED COMPONENTS core imgproc imgcodecs videoio) -# find_package(Boost REQUIRED COMPONENTS system url) - -add_subdirectory(source/cli) diff --git a/CMakePresets.json b/CMakePresets.json deleted file mode 100644 index 6eda756..0000000 --- a/CMakePresets.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "version": 5, - "cmakeMinimumRequired": { - "major": 3, - "minor": 21, - "patch": 0 - }, - "configurePresets": [ - { - "name": "NinjaMulti", - "displayName": "Ninja MultiConfig", - "description": "Ninja MultiConfig", - "generator": "Ninja Multi-Config", - "binaryDir": "${sourceDir}/build" - }, - { - "name": "MSVC 2022", - "displayName": "MSVC 2022", - "description": "MSVC 2022", - "generator": "Visual Studio 17 2022", - "binaryDir": "${sourceDir}/build", - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Windows" - } - }, - { - "name": "MSVC 2022 ARM", - "displayName": "MSVC 2022 ARM", - "description": "MSVC 2022 ARM", - "generator": "Visual Studio 17 2022", - "binaryDir": "${sourceDir}/build", - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Windows" - }, - "architecture": { - "strategy": "set", - "value": "ARM64" - } - } - ] -} diff --git a/assets/MaaCommonAssets b/assets/MaaCommonAssets new file mode 160000 index 0000000..270c3e7 --- /dev/null +++ b/assets/MaaCommonAssets @@ -0,0 +1 @@ +Subproject commit 270c3e77d4303ae14ea1c4ef9a084f713ca495ab diff --git a/assets/interface.json b/assets/interface.json new file mode 100644 index 0000000..e580d53 --- /dev/null +++ b/assets/interface.json @@ -0,0 +1,48 @@ +{ + "controller": [ + { + "name": "ADB 默认方式", + "type": "Adb", + "screencap": 16580608 + } + ], + "resource": [ + { + "name": "官服", + "path": [ + "{PROJECT_DIR}/resource/base" + ] + } + ], + "task": [ + { + "name": "签到", + "entry": "Skland", + "option": [ + "关闭森空岛" + ] + } + ], + "option": { + "关闭森空岛": { + "cases": [ + { + "name": "启用", + "param": { + "CloseSkland": { + "enabled": true + } + } + }, + { + "name": "禁用", + "param": { + "CloseSkland": { + "enabled": false + } + } + } + ] + } + } +} \ No newline at end of file diff --git a/assets/resource/image/Skland/EnterArknightsPage_0.png b/assets/resource/base/image/Skland/EnterArknightsPage_0.png similarity index 100% rename from assets/resource/image/Skland/EnterArknightsPage_0.png rename to assets/resource/base/image/Skland/EnterArknightsPage_0.png diff --git a/assets/resource/image/Skland/EnterArknightsPage_1.png b/assets/resource/base/image/Skland/EnterArknightsPage_1.png similarity index 100% rename from assets/resource/image/Skland/EnterArknightsPage_1.png rename to assets/resource/base/image/Skland/EnterArknightsPage_1.png diff --git a/assets/resource/image/Skland/EnterSignInBenefitsPage.png b/assets/resource/base/image/Skland/EnterSignInBenefitsPage.png similarity index 100% rename from assets/resource/image/Skland/EnterSignInBenefitsPage.png rename to assets/resource/base/image/Skland/EnterSignInBenefitsPage.png diff --git a/assets/resource/image/Skland/Receive.png b/assets/resource/base/image/Skland/Receive.png similarity index 100% rename from assets/resource/image/Skland/Receive.png rename to assets/resource/base/image/Skland/Receive.png diff --git a/assets/resource/image/Skland/SignInBenefitsPageFlag.png b/assets/resource/base/image/Skland/SignInBenefitsPageFlag.png similarity index 100% rename from assets/resource/image/Skland/SignInBenefitsPageFlag.png rename to assets/resource/base/image/Skland/SignInBenefitsPageFlag.png diff --git a/assets/resource/base/model/ocr/README.md b/assets/resource/base/model/ocr/README.md new file mode 100644 index 0000000..1bb517f --- /dev/null +++ b/assets/resource/base/model/ocr/README.md @@ -0,0 +1,23 @@ +# PaddleOCR model + +2023/09/29 + +from + +## det model + +ch_PP-OCRv4_det +【最新】原始超轻量模型,支持中英文、多语种文本检测 + + + +## rec model + +ch_PP-OCRv4_rec +【最新】超轻量模型,支持中英文、数字识别 + + + +## rec label + + diff --git a/assets/resource/base/model/ocr/det.onnx b/assets/resource/base/model/ocr/det.onnx new file mode 100644 index 0000000..5d1f1cd Binary files /dev/null and b/assets/resource/base/model/ocr/det.onnx differ diff --git a/assets/resource/model/ocr/keys.txt b/assets/resource/base/model/ocr/keys.txt similarity index 100% rename from assets/resource/model/ocr/keys.txt rename to assets/resource/base/model/ocr/keys.txt diff --git a/assets/resource/model/ocr/rec.onnx b/assets/resource/base/model/ocr/rec.onnx similarity index 56% rename from assets/resource/model/ocr/rec.onnx rename to assets/resource/base/model/ocr/rec.onnx index 98324d6..b521ed3 100644 Binary files a/assets/resource/model/ocr/rec.onnx and b/assets/resource/base/model/ocr/rec.onnx differ diff --git a/assets/resource/pipeline.schema.json b/assets/resource/base/pipeline.schema.json similarity index 100% rename from assets/resource/pipeline.schema.json rename to assets/resource/base/pipeline.schema.json diff --git a/assets/resource/pipeline/skland.json b/assets/resource/base/pipeline/skland.json similarity index 95% rename from assets/resource/pipeline/skland.json rename to assets/resource/base/pipeline/skland.json index fd6a667..cdc5176 100644 --- a/assets/resource/pipeline/skland.json +++ b/assets/resource/base/pipeline/skland.json @@ -1,5 +1,4 @@ { - "$schema": "../pipeline.schema.json", "Skland": { "next": [ "IgnoreUpdates", @@ -11,15 +10,17 @@ }, "Sub_StartSkland": { "is_sub": true, - "action": "StartApp" + "action": "StartApp", + "package": "com.hypergryph.skland/com.hypergryph.skland.SplashActivity" }, "CloseSkland": { "enabled": false, - "action": "StopApp" + "action": "StopApp", + "package": "com.hypergryph.skland" }, "IgnoreUpdates": { "recognition": "OCR", - "text": [ + "expected": [ "下次再说" ], "roi": [ @@ -114,7 +115,7 @@ }, "NotReceiveBox_1": { "recognition": "OCR", - "text": [ + "expected": [ "已", "领取" ], @@ -149,7 +150,7 @@ }, "NotReceiveBox_2": { "recognition": "OCR", - "text": [ + "expected": [ "已", "领取" ], @@ -184,7 +185,7 @@ }, "NotReceiveBox_3": { "recognition": "OCR", - "text": [ + "expected": [ "已", "领取" ], @@ -219,7 +220,7 @@ }, "NotReceiveBox_4": { "recognition": "OCR", - "text": [ + "expected": [ "已", "领取" ], @@ -254,7 +255,7 @@ }, "NotReceiveBox_5": { "recognition": "OCR", - "text": [ + "expected": [ "已", "领取" ], @@ -289,7 +290,7 @@ }, "NotReceiveBox_6": { "recognition": "OCR", - "text": [ + "expected": [ "已", "领取" ], @@ -324,7 +325,7 @@ }, "NotReceiveBox_7": { "recognition": "OCR", - "text": [ + "expected": [ "已", "领取" ], @@ -340,4 +341,4 @@ ] }, "Stop": {} -} +} \ No newline at end of file diff --git a/assets/resource/model/ocr/README.md b/assets/resource/model/ocr/README.md deleted file mode 100644 index fcc52e2..0000000 --- a/assets/resource/model/ocr/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# PaddleOCR model - -2023/07/06 - -from - -## det model - -ch_PP-OCRv3_det [New] Original lightweight model, supporting Chinese, English, multilingual text detection - - - -## rec model - -ch_PP-OCRv3_rec [New] Original lightweight model, supporting Chinese, English, multilingual text recognition - - - -## rec label - - - -## command - -### det - -```bash -$ paddle2onnx --model_dir . --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file det_unopt.onnx --opset_version 16 --enable_dev_version True --enable_onnx_checker True --deploy_backend onnxruntime -[Paddle2ONNX] Start to parse PaddlePaddle model... -[Paddle2ONNX] Model file path: ./inference.pdmodel -[Paddle2ONNX] Paramters file path: ./inference.pdiparams -[Paddle2ONNX] Start to parsing Paddle model... -[Paddle2ONNX] Use opset_version = 16 for ONNX export. -[Paddle2ONNX] PaddlePaddle model is exported as ONNX format now. -2023-07-06 23:36:40 [INFO] ===============Make PaddlePaddle Better!================ -2023-07-06 23:36:40 [INFO] A little survey: https://iwenjuan.baidu.com/?code=r8hu2s -``` - -```bash -$ python -m paddle2onnx.optimize --input_model det_unopt.onnx --output_model det.onnx -2023-07-06 23:37:06 [INFO] Model optmized, saved in det.onnx. -``` - -### rec - -```bash -$ paddle2onnx --model_dir . --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file rec_unopt.onnx --opset_version 16 --enable_dev_version True --enable_onnx_checker True --deploy_backend onnxruntime -[Paddle2ONNX] Start to parse PaddlePaddle model... -[Paddle2ONNX] Model file path: ./inference.pdmodel -[Paddle2ONNX] Paramters file path: ./inference.pdiparams -[Paddle2ONNX] Start to parsing Paddle model... -[Paddle2ONNX] Use opset_version = 16 for ONNX export. -[Paddle2ONNX] PaddlePaddle model is exported as ONNX format now. -2023-07-06 23:37:28 [INFO] ===============Make PaddlePaddle Better!================ -2023-07-06 23:37:28 [INFO] A little survey: https://iwenjuan.baidu.com/?code=r8hu2s -``` - -```bash -$ python -m paddle2onnx.optimize --input_model rec_unopt.onnx --output_model rec.onnx -2023-07-06 23:37:37 [INFO] Model optmized, saved in rec.onnx. -``` diff --git a/assets/resource/model/ocr/det.onnx b/assets/resource/model/ocr/det.onnx deleted file mode 100644 index 9a327d9..0000000 Binary files a/assets/resource/model/ocr/det.onnx and /dev/null differ diff --git a/assets/resource/properties.json b/assets/resource/properties.json deleted file mode 100644 index ba0f235..0000000 --- a/assets/resource/properties.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "is_base": true -} \ No newline at end of file diff --git a/cmake/assets.cmake b/cmake/assets.cmake deleted file mode 100644 index 1fe0172..0000000 --- a/cmake/assets.cmake +++ /dev/null @@ -1,9 +0,0 @@ -set(maa_assets_target ${CMAKE_BINARY_DIR}) - -add_custom_command(OUTPUT ${maa_assets_target}/resource - COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/assets/resource ${maa_assets_target}/resource -) -add_custom_target(AssetsResource ALL DEPENDS ${maa_assets_target}/resource) -set_property(TARGET AssetsResource APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${maa_assets_target}/resource) -set_target_properties(AssetsResource PROPERTIES FOLDER Assets) -install(DIRECTORY ${PROJECT_SOURCE_DIR}/assets/resource DESTINATION .) diff --git a/cmake/config.cmake b/cmake/config.cmake deleted file mode 100644 index 36a6a82..0000000 --- a/cmake/config.cmake +++ /dev/null @@ -1,44 +0,0 @@ -set(debug_comp_defs "_DEBUG;MAA_DEBUG") -add_compile_definitions("$<$:${debug_comp_defs}>") - -set(rel_debug_comp_defs "MAA_DEBUG") - -if (MSVC) - add_compile_options("/utf-8") - add_compile_options("/MP") - add_compile_options("/W4;/WX;/Gy;/permissive-;/sdl") - add_compile_options("/wd4127") # conditional expression is constant - add_compile_options("/wd4251") # export dll with templates - - set(rel_debug_comp_options "/Od") - - set(release_link_options "/OPT:REF;/OPT:ICF") - add_link_options("$<$:${release_link_options}>") - - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") -else () - add_compile_options("-Wall;-Werror;-Wextra;-Wpedantic;-Wno-missing-field-initializers") - if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13) - add_compile_options("-Wno-restrict") - endif() - - set(rel_debug_comp_options "-O0") -endif () - -if (APPLE) - set(CMAKE_INSTALL_RPATH "@loader_path;@executable_path") - add_compile_options("-Wno-deprecated-declarations") # supress tmpnam - if ("${ARCH}" STREQUAL "arm64") - add_compile_options("-arch;arm64") - add_link_options("-arch;arm64") - endif () -elseif (UNIX) - set(CMAKE_INSTALL_RPATH "$ORIGIN") -endif () - -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) diff --git a/cmake/framework.cmake b/cmake/framework.cmake deleted file mode 100644 index f0b9319..0000000 --- a/cmake/framework.cmake +++ /dev/null @@ -1,2 +0,0 @@ -install(DIRECTORY "${CMAKE_SOURCE_DIR}/deps/bin/" DESTINATION .) -install(DIRECTORY "${CMAKE_SOURCE_DIR}/deps/share/MaaAgentBinary" DESTINATION .) diff --git a/cmake/macos.cmake b/cmake/macos.cmake deleted file mode 100644 index 2bd501a..0000000 --- a/cmake/macos.cmake +++ /dev/null @@ -1,20 +0,0 @@ -if (BUILD_XCFRAMEWORK) - add_custom_command(OUTPUT MaaFramework.xcframework - COMMAND rm -rf MaaFramework.xcframework - COMMAND xcodebuild -create-xcframework -library libMaaFramework.dylib -headers ${PROJECT_SOURCE_DIR}/include -output MaaFramework.xcframework - DEPENDS MaaFramework - ) - - add_custom_command(OUTPUT OpenCV.xcframework - COMMAND rm -rf OpenCV.xcframework - COMMAND xcodebuild -create-xcframework -library "${PROJECT_SOURCE_DIR}/MaaDeps/runtime/${MAADEPS_TRIPLET}/libopencv_world4.407.dylib" -output OpenCV.xcframework - ) - - add_custom_target(MaaXCFramework ALL - DEPENDS MaaFramework MaaFramework.xcframework OpenCV.xcframework - ) -endif (BUILD_XCFRAMEWORK) - -target_compile_options(MaaFramework PRIVATE - -Wno-deprecated-declarations - -Wno-gnu-zero-variadic-macro-arguments) diff --git a/cmake/utils.cmake b/cmake/utils.cmake deleted file mode 100644 index be4a139..0000000 --- a/cmake/utils.cmake +++ /dev/null @@ -1,30 +0,0 @@ -function(download_and_decompress url filename sha256_checksum decompress_dir) - if(EXISTS ${filename}) - file(SHA256 ${filename} CHECKSUM_VARIABLE) - endif() - if(NOT EXISTS ${filename} OR NOT CHECKSUM_VARIABLE STREQUAL sha256_checksum) - message("Downloading file from ${url} to ${filename} ...") - file(DOWNLOAD ${url} "${filename}.tmp" SHOW_PROGRESS EXPECTED_HASH SHA256=${sha256_checksum}) - file(RENAME "${filename}.tmp" ${filename}) - endif() - if(NOT EXISTS ${decompress_dir}) - file(MAKE_DIRECTORY ${decompress_dir}) - endif() - message("Decompress file ${filename} ...") - execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${filename} WORKING_DIRECTORY ${decompress_dir}) -endfunction() - -function(get_osx_architecture) - if (CMAKE_OSX_ARCHITECTURES STREQUAL "arm64") - set(CURRENT_OSX_ARCH "arm64" PARENT_SCOPE) - elseif(CMAKE_OSX_ARCHITECTURES STREQUAL "x86_64") - set(CURRENT_OSX_ARCH "x86_64" PARENT_SCOPE) - else() - set(CURRENT_OSX_ARCH ${CMAKE_HOST_SYSTEM_PROCESSOR} PARENT_SCOPE) - endif() -endfunction() - -if (APPLE) - set(CMAKE_OSX_DEPLOYMENT_TARGET 12.0) - get_osx_architecture() -endif (APPLE) diff --git a/cmake/version.cmake b/cmake/version.cmake deleted file mode 100644 index 363b68f..0000000 --- a/cmake/version.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# define MAS_HASH_VERSION from git -set(MAS_HASH_VERSION "DEBUG_VERSION" CACHE STRING "maaskland version") -if (MAS_HASH_VERSION STREQUAL "DEBUG_VERSION") - find_package(Git) -endif () -if (MAS_HASH_VERSION STREQUAL "DEBUG_VERSION" AND GIT_FOUND) - execute_process( - COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE result - OUTPUT_VARIABLE output - ERROR_VARIABLE err - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if (result EQUAL 0) - set(MAS_HASH_VERSION "${output}") - else () - message(WARNING "git rev-parse returning ${result}, output:\n${err}") - endif () -endif () -message(STATUS "MAS_HASH_VERSION=${MAS_HASH_VERSION}") -add_compile_definitions(MAS_VERSION="${MAS_HASH_VERSION}") diff --git a/configure.py b/configure.py new file mode 100644 index 0000000..894d294 --- /dev/null +++ b/configure.py @@ -0,0 +1,17 @@ +from pathlib import Path + +import shutil + +assets_dir = Path(__file__).parent / "assets" + + +def configure_ocr_model(): + shutil.copytree( + assets_dir / "MaaCommonAssets" / "OCR" / "ppocr_v4" / "zh_cn", + assets_dir / "resource" / "base" / "model" / "ocr", + dirs_exist_ok=True, + ) + + +if __name__ == "__main__": + configure_ocr_model() diff --git a/install.py b/install.py new file mode 100644 index 0000000..51ba79a --- /dev/null +++ b/install.py @@ -0,0 +1,72 @@ +from pathlib import Path + +import shutil +import sys +import json + +from configure import configure_ocr_model + + +working_dir = Path(__file__).parent +install_path = working_dir / Path("install") +version = len(sys.argv) > 1 and sys.argv[1] or "v0.0.1" + + +def install_deps(): + shutil.copytree( + working_dir / "deps" / "bin", + install_path, + ignore=shutil.ignore_patterns( + "*MaaDbgControlUnit*", + "*MaaThriftControlUnit*", + "*MaaWin32ControlUnit*", + "*MaaRpc*", + "*MaaHttp*", + ), + dirs_exist_ok=True, + ) + shutil.copytree( + working_dir / "deps" / "share" / "MaaAgentBinary", + install_path / "MaaAgentBinary", + dirs_exist_ok=True, + ) + + +def install_resource(): + + configure_ocr_model() + + shutil.copytree( + working_dir / "assets" / "resource", + install_path / "resource", + dirs_exist_ok=True, + ) + shutil.copy2( + working_dir / "assets" / "interface.json", + install_path, + ) + + with open(install_path / "interface.json", "r", encoding="utf-8") as f: + interface = json.load(f) + + interface["version"] = version + + with open(install_path / "interface.json", "w", encoding="utf-8") as f: + json.dump(interface, f, ensure_ascii=False, indent=4) + + +def install_chores(): + shutil.copy2( + working_dir / "README.md", + install_path, + ) + shutil.copy2( + working_dir / "LICENSE", + install_path, + ) + + +if __name__ == "__main__": + install_deps() + install_resource() + install_chores() diff --git a/source/cli/.clang-format b/source/cli/.clang-format deleted file mode 100644 index c77d678..0000000 --- a/source/cli/.clang-format +++ /dev/null @@ -1,195 +0,0 @@ -Language: Json -ColumnLimit: 1000 -IndentWidth: 4 ---- -Language: Cpp -AccessModifierOffset: -4 -AlignAfterOpenBracket: Align -AlignArrayOfStructures: None -AlignConsecutiveMacros: None -AlignConsecutiveAssignments: None -AlignConsecutiveBitFields: None -AlignConsecutiveDeclarations: None -AlignEscapedNewlines: Left -AlignOperands: Align -AlignTrailingComments: true -AllowAllArgumentsOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortEnumsOnASingleLine: false -AllowShortBlocksOnASingleLine: Empty -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: Inline -AllowShortLambdasOnASingleLine: All -AllowShortIfStatementsOnASingleLine: WithoutElse -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: true -AttributeMacros: - - __capability -BinPackArguments: true -BinPackParameters: true -BraceWrapping: - AfterCaseLabel: false - AfterClass: true - AfterControlStatement: Never - AfterEnum: true - AfterFunction: true - AfterNamespace: true - AfterObjCDeclaration: true - AfterStruct: true - AfterUnion: false - AfterExternBlock: true - BeforeCatch: true - BeforeElse: true - BeforeLambdaBody: false - BeforeWhile: false - IndentBraces: false - SplitEmptyFunction: false - SplitEmptyRecord: false - SplitEmptyNamespace: false -BreakBeforeBinaryOperators: None -BreakBeforeConceptDeclarations: true -BreakBeforeBraces: Custom -BreakBeforeInheritanceComma: false -BreakInheritanceList: BeforeColon -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BreakConstructorInitializers: BeforeColon -BreakAfterJavaFieldAnnotations: false -BreakStringLiterals: true -ColumnLimit: 120 -CommentPragmas: '^ IWYU pragma:' -QualifierAlignment: Leave -CompactNamespaces: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: false -DeriveLineEnding: true -DerivePointerAlignment: false -DisableFormat: false -EmptyLineAfterAccessModifier: Never -EmptyLineBeforeAccessModifier: LogicalBlock -ExperimentalAutoDetectBinPacking: false -PackConstructorInitializers: BinPack -BasedOnStyle: '' -ConstructorInitializerAllOnOneLineOrOnePerLine: false -AllowAllConstructorInitializersOnNextLine: true -FixNamespaceComments: true -ForEachMacros: - - foreach - - Q_FOREACH - - BOOST_FOREACH -IfMacros: - - KJ_IF_MAYBE -IncludeBlocks: Preserve -IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - SortPriority: 0 - CaseSensitive: false - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 3 - SortPriority: 0 - CaseSensitive: false - - Regex: '.*' - Priority: 1 - SortPriority: 0 - CaseSensitive: false -IncludeIsMainRegex: '(Test)?$' -IncludeIsMainSourceRegex: '' -IndentAccessModifiers: false -IndentCaseLabels: false -IndentCaseBlocks: false -IndentGotoLabels: true -IndentPPDirectives: None -IndentExternBlock: AfterExternBlock -IndentRequiresClause: false -IndentWidth: 4 -IndentWrappedFunctionNames: false -InsertTrailingCommas: None -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true -LambdaBodyIndentation: Signature -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: Inner -ObjCBinPackProtocolList: Auto -ObjCBlockIndentWidth: 2 -ObjCBreakBeforeNestedBlockParam: true -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakOpenParenthesis: 0 -PenaltyBreakString: 1000 -PenaltyBreakTemplateDeclaration: 10 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 1000 -PenaltyIndentedWhitespace: 0 -PointerAlignment: Left -PPIndentWidth: -1 -ReferenceAlignment: Pointer -ReflowComments: true -RemoveBracesLLVM: false -RequiresClausePosition: OwnLine -SeparateDefinitionBlocks: Leave -ShortNamespaceLines: 50 -SortIncludes: CaseSensitive -SortJavaStaticImport: Before -SortUsingDeclarations: true -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeCaseColon: false -SpaceBeforeCpp11BracedList: true -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeParensOptions: - AfterControlStatements: true - AfterForeachMacros: true - AfterFunctionDefinitionName: false - AfterFunctionDeclarationName: false - AfterIfMacros: true - AfterOverloadedOperator: false - AfterRequiresInClause: true - AfterRequiresInExpression: true - BeforeNonEmptyParentheses: false -SpaceAroundPointerQualifiers: Default -SpaceBeforeRangeBasedForLoopColon: true -SpaceInEmptyBlock: false -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: Never -SpacesInConditionalStatement: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInLineCommentPrefix: - Minimum: 1 - Maximum: -1 -SpacesInParentheses: false -SpacesInSquareBrackets: false -SpaceBeforeSquareBrackets: false -BitFieldColonSpacing: Both -Standard: c++20 -StatementAttributeLikeMacros: - - Q_EMIT -StatementMacros: - - Q_UNUSED - - QT_REQUIRE_VERSION -TabWidth: 4 -UseCRLF: false -UseTab: Never -WhitespaceSensitiveMacros: - - STRINGIZE - - PP_STRINGIZE - - BOOST_PP_STRINGIZE - - NS_SWIFT_NAME - - CF_SWIFT_NAME diff --git a/source/cli/CMakeLists.txt b/source/cli/CMakeLists.txt deleted file mode 100644 index f61b3f5..0000000 --- a/source/cli/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -include_directories(${CMAKE_SOURCE_DIR}/deps/include) -if (WIN32) - link_directories(${CMAKE_SOURCE_DIR}/deps/lib) -else () - link_directories(${CMAKE_SOURCE_DIR}/deps/bin) -endif () - -set(CMAKE_BUILD_TYPE "Release") -set(CMAKE_CONFIGURATION_TYPES "Release") - -add_executable(MAS_CLI main.cpp main.h) -target_link_libraries(MAS_CLI PRIVATE MaaFramework MaaToolKit) - -add_dependencies(MAS_CLI AssetsResource) - -install(TARGETS MAS_CLI RUNTIME DESTINATION .) diff --git a/source/cli/main.cpp b/source/cli/main.cpp deleted file mode 100644 index 887ebfb..0000000 --- a/source/cli/main.cpp +++ /dev/null @@ -1,333 +0,0 @@ -#include "main.h" - -int main(int argc, char** argv) -{ - MaaToolKitInit(); - - print_help(); - print_version(); - - bool debug = false; - std::string adb; - std::string adb_address; - std::string package = "com.hypergryph.skland"; - std::string activity = "com.hypergryph.skland/com.hypergryph.skland.SplashActivity"; - TaskList tasks; - MaaAdbControllerType control_type = 0; - - auto device_size = scanning_devices(); - if (device_size == 0) { - mpause(); - return -1; - } - bool proced = proc_argv(argc, argv, debug, adb, adb_address, tasks, control_type); - if (!proced) { - std::cout << "Failed to parse argv" << std::endl; - mpause(); - return -1; - } - if (tasks.empty()) { - std::cout << "Task empty" << std::endl; - mpause(); - return -1; - } - - bool matched = false; - MaaSize kIndex = 0; - if (!adb.empty() && !adb_address.empty()) { - matched = match_adb_address(adb_address, kIndex, device_size); - } - if (!matched) { - kIndex = get_device_index(device_size); - adb = MaaToolKitGetDeviceAdbPath(kIndex); - adb_address = MaaToolKitGetDeviceAdbSerial(kIndex); - save_config(adb, adb_address, tasks, control_type); - } - - const auto cur_dir = std::filesystem::path(argv[0]).parent_path(); - std::string debug_dir = (cur_dir / "debug").string(); - std::string resource_dir = (cur_dir / "resource").string(); - std::string adb_config = MaaToolKitGetDeviceAdbConfig(kIndex); - - MaaSetGlobalOption(MaaGlobalOption_Logging, (void*)debug_dir.c_str(), debug_dir.size()); - MaaSetGlobalOption(MaaGlobalOption_DebugMode, (void*)&debug, sizeof(bool)); - - auto maa_handle = MaaCreate(nullptr, nullptr); - auto resource_handle = MaaResourceCreate(nullptr, nullptr); - auto controller_handle = MaaAdbControllerCreate(adb.c_str(), adb_address.c_str(), control_type, adb_config.c_str(), nullptr, nullptr); - - MaaBindResource(maa_handle, resource_handle); - MaaBindController(maa_handle, controller_handle); - int height = 720; - MaaControllerSetOption(controller_handle, MaaCtrlOption_ScreenshotTargetShortSide, reinterpret_cast(&height), sizeof(int)); - MaaControllerSetOption(controller_handle, MaaCtrlOption_DefaultAppPackageEntry, (void*)activity.c_str(), activity.size()); - MaaControllerSetOption(controller_handle, MaaCtrlOption_DefaultAppPackage, (void*)package.c_str(), package.size()); - - auto resource_id = MaaResourcePostPath(resource_handle, resource_dir.c_str()); - auto connection_id = MaaControllerPostConnection(controller_handle); - - MaaResourceWait(resource_handle, resource_id); - MaaControllerWait(controller_handle, connection_id); - - auto destroy = [&]() { - MaaDestroy(maa_handle); - MaaResourceDestroy(resource_handle); - MaaControllerDestroy(controller_handle); - MaaToolKitUninit(); - }; - - if (!MaaInited(maa_handle)) { - destroy(); - std::cout << "Failed to init Maa instance, a connection error or resource file corruption occurred, please refer to the log." << std::endl; - mpause(); - return -1; - } - - MaaTaskId task_id = 0; - for (const auto& task : tasks) { - if (!task.enabled) - { - continue; - } - std::cout << task.type << " Start" << std::endl; - task_id = MaaPostTask(maa_handle, task.type.c_str(), task.param.to_string().c_str()); - std::cout << task.type << " Running..." << std::endl; - auto end_status = MaaWaitTask(maa_handle, task_id); - std::cout << task.type << " End" << std::endl - << task.type << " Result: " << task_status(end_status) << std::endl; - } - - std::cout << std::endl << "All Tasks Over" << std::endl; - - destroy(); - - return 0; -} - -void print_help() -{ - std::cout << - R"(MAS CLI -Github: https://github.com/MaaAssistantArknights/MaaAssistantSkland - -Usage: MAS_CLI.exe [adb_path] [adb_address] [task_name]... - -Modify config.json to configure tasks. - -Welcome to come and create a GUI for us! :) -)" << std::endl; -} - -void print_version() -{ - std::cout << "MaaFramework Version: " << MaaVersion() << std::endl - << "MAS Version: " << MAS_VERSION << std::endl - << std::endl; -} - -MaaSize scanning_devices() -{ - std::cout << "Scanning for Devices..." << std::endl; - auto device_size = MaaToolKitFindDevice(); - if (device_size == 0) { - std::cout << "No Devices Found" << std::endl; - return 0; - } - std::cout << "Scanning Finished" - << std::endl - << std::endl; - return device_size; -} - -bool match_adb_address(const std::string& adb_address, MaaSize& index, const MaaSize& device_size) -{ - for (MaaSize i = 0; i < device_size; i++) { - if (adb_address == MaaToolKitGetDeviceAdbSerial(i)) { - index = i; - return true; - } - } - return false; -} - -void print_device_list(const MaaSize& device_size) { - for (MaaSize i = 0; i < device_size; i++) { - std::cout << " " << i << ". " << MaaToolKitGetDeviceName(i) << " (" << MaaToolKitGetDeviceAdbSerial(i) << ")\n"; - } -} - -MaaSize get_device_index(const MaaSize& device_size) -{ - MaaSize index; - while (true) { - std::cout << std::endl - << "Please Select a Device to Connect:" - << std::endl - << std::endl; - print_device_list(device_size); - std::cout << std::endl - << "Please Enter the Device Number:" - << std::endl; - std::cin >> index; - if (index > device_size) { - std::cout << std::endl - << "Unknown Device Number: " << index - << std::endl - << std::endl; - continue; - } - std::cout << std::endl; - break; - } - return index; -} - -json::value skland_param() { - json::value param; - auto& diff = param["diff_task"]; - auto& close_skland_enabled = diff["CloseSkland"]["enabled"]; - - close_skland_enabled = false; - - return param; -} - -bool proc_argv(int argc, char** argv, bool& debug, std::string& adb, std::string& adb_address, TaskList& tasks, - MaaAdbControllerType& ctrl_type) -{ - int touch = 1; - int key = 1; - int screencap = 3; - - tasks.clear(); - - if (auto config_opt = json::open("config.json")) { - auto& confing = *config_opt; - - debug = confing.get("debug", false); - adb = confing["adb"].as_string(); - adb_address = confing["adb_address"].as_string(); - - int index = 1; - for (auto& task : confing["tasks"].as_array()) { - Task task_obj; - if (task.is_string()) { - task_obj.type = task.as_string(); - task_obj.name = "MyTask" + std::to_string(index++); - } - else { - task_obj.enabled = task.get("enabled", true); - if (!task_obj.enabled) { - continue; - } - task_obj.type = task["type"].as_string(); - task_obj.name = task["name"].as_string(); - task_obj.param = task["param"]; - } - tasks.emplace_back(task_obj); - } - touch = confing.get("touch", touch); - key = confing.get("key", key); - screencap = confing.get("screencap", screencap); - - ctrl_type = touch << 0 | key << 8 | screencap << 16; - } - else { - Task task_obj; - task_obj.name = "MyTask1"; - task_obj.type = "Skland"; - task_obj.param = skland_param(); - tasks.emplace_back(std::move(task_obj)); - - ctrl_type = touch << 0 | key << 8 | screencap << 16; - } - - if (argc >= 3) { - adb = argv[1]; - adb_address = argv[2]; - - std::vector task_names; - for (int i = 3; i < argc; ++i) { - task_names.emplace_back(argv[i]); - } - auto all_tasks = std::move(tasks); - tasks.clear(); - for (auto& task_name : task_names) { - for (auto& task : all_tasks) { - if (task.name == task_name) { - task.enabled = true; - tasks.emplace_back(task); - break; - } - } - } - } - - return true; -} - -void save_config(const std::string& adb, const std::string& adb_address, const TaskList& tasks, - MaaAdbControllerType ctrl_type) -{ - json::value config; - config["debug"] = false; - config["adb"] = adb; - config["adb_Doc"] = "adb.exe 所在路径,相对绝对均可"; - config["adb_address"] = adb_address; - config["adb_address_Doc"] = "adb 连接地址,例如 127.0.0.1:7555"; - - json::value tasks_array; - for (auto& task : tasks) { - json::value task_obj; - task_obj["enabled"] = task.enabled; - task_obj["type"] = task.type; - task_obj["name"] = task.name; - task_obj["param"] = task.param; - tasks_array.emplace(std::move(task_obj)); - } - config["tasks"] = std::move(tasks_array); - config["tasks_Doc"] = "要执行的任务"; - - config["touch"] = (ctrl_type & MaaAdbControllerType_Touch_Mask) >> 0; - config["touch_Doc"] = "点击方式:1: Adb, 2: MiniTouch, 3: MaaTouch"; - // config["key"] = key; - // config["key_Doc"] = "按键方式:1: Adb, 2: MaaTouch"; - config["screencap"] = (ctrl_type & MaaAdbControllerType_Screencap_Mask) >> 16; - config["screencap_Doc"] = "截图方式:1: 自动测速, 2: RawByNetcat, 3: RawWithGzip, 4: Encode, 5: EncodeToFile, 6: " - "MinicapDirect, 7: MinicapStream"; - config["version"] = "v0.1.0"; - - std::ofstream ofs("config.json", std::ios::out); - ofs << config; - ofs.close(); -} - -std::string task_status(MaaStatus status) { - std::string task_status; - switch (status) { - case MaaStatus_Invalid: - task_status = "Invalid"; - break; - case MaaStatus_Pending: - task_status = "Pending"; - break; - case MaaStatus_Running: - task_status = "Running"; - break; - case MaaStatus_Success: - task_status = "Success"; - break; - case MaaStatus_Failed: - task_status = "Failed"; - break; - default: - task_status = "Unkown"; - break; - } - return task_status; -} - -void mpause() -{ - std::ignore = getchar(); -} \ No newline at end of file diff --git a/source/cli/main.h b/source/cli/main.h deleted file mode 100644 index 3b7c886..0000000 --- a/source/cli/main.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "MaaFramework/MaaAPI.h" -#include "MaaToolKit/MaaToolKitAPI.h" -#include "meojson/json.hpp" - -struct Task -{ - std::string name; - std::string type; - bool enabled = true; - json::value param = json::object(); -}; - -using TaskList = std::vector; - -void print_help(); - -void print_version(); - -MaaSize scanning_devices(); - -json::value skland_param(); - -bool proc_argv(int argc, char** argv, bool& debug, std::string& adb, std::string& adb_address, - TaskList& tasks, MaaAdbControllerType& ctrl_type); - -bool match_adb_address(const std::string& adb_address, MaaSize& index , const MaaSize& device_size); - -void print_device_list(const MaaSize& device_size); - -MaaSize get_device_index(const MaaSize& device_size); - -void save_config(const std::string& adb, const std::string& adb_address, const TaskList& tasks, - MaaAdbControllerType ctrl_type); - -std::string read_adb_config(const std::filesystem::path& cur_dir); - -std::string task_status(MaaStatus status); - -void mpause(); \ No newline at end of file diff --git a/source/cli/meojson/.clang-format b/source/cli/meojson/.clang-format deleted file mode 100644 index c77d678..0000000 --- a/source/cli/meojson/.clang-format +++ /dev/null @@ -1,195 +0,0 @@ -Language: Json -ColumnLimit: 1000 -IndentWidth: 4 ---- -Language: Cpp -AccessModifierOffset: -4 -AlignAfterOpenBracket: Align -AlignArrayOfStructures: None -AlignConsecutiveMacros: None -AlignConsecutiveAssignments: None -AlignConsecutiveBitFields: None -AlignConsecutiveDeclarations: None -AlignEscapedNewlines: Left -AlignOperands: Align -AlignTrailingComments: true -AllowAllArgumentsOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortEnumsOnASingleLine: false -AllowShortBlocksOnASingleLine: Empty -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: Inline -AllowShortLambdasOnASingleLine: All -AllowShortIfStatementsOnASingleLine: WithoutElse -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: true -AttributeMacros: - - __capability -BinPackArguments: true -BinPackParameters: true -BraceWrapping: - AfterCaseLabel: false - AfterClass: true - AfterControlStatement: Never - AfterEnum: true - AfterFunction: true - AfterNamespace: true - AfterObjCDeclaration: true - AfterStruct: true - AfterUnion: false - AfterExternBlock: true - BeforeCatch: true - BeforeElse: true - BeforeLambdaBody: false - BeforeWhile: false - IndentBraces: false - SplitEmptyFunction: false - SplitEmptyRecord: false - SplitEmptyNamespace: false -BreakBeforeBinaryOperators: None -BreakBeforeConceptDeclarations: true -BreakBeforeBraces: Custom -BreakBeforeInheritanceComma: false -BreakInheritanceList: BeforeColon -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BreakConstructorInitializers: BeforeColon -BreakAfterJavaFieldAnnotations: false -BreakStringLiterals: true -ColumnLimit: 120 -CommentPragmas: '^ IWYU pragma:' -QualifierAlignment: Leave -CompactNamespaces: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: false -DeriveLineEnding: true -DerivePointerAlignment: false -DisableFormat: false -EmptyLineAfterAccessModifier: Never -EmptyLineBeforeAccessModifier: LogicalBlock -ExperimentalAutoDetectBinPacking: false -PackConstructorInitializers: BinPack -BasedOnStyle: '' -ConstructorInitializerAllOnOneLineOrOnePerLine: false -AllowAllConstructorInitializersOnNextLine: true -FixNamespaceComments: true -ForEachMacros: - - foreach - - Q_FOREACH - - BOOST_FOREACH -IfMacros: - - KJ_IF_MAYBE -IncludeBlocks: Preserve -IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - SortPriority: 0 - CaseSensitive: false - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 3 - SortPriority: 0 - CaseSensitive: false - - Regex: '.*' - Priority: 1 - SortPriority: 0 - CaseSensitive: false -IncludeIsMainRegex: '(Test)?$' -IncludeIsMainSourceRegex: '' -IndentAccessModifiers: false -IndentCaseLabels: false -IndentCaseBlocks: false -IndentGotoLabels: true -IndentPPDirectives: None -IndentExternBlock: AfterExternBlock -IndentRequiresClause: false -IndentWidth: 4 -IndentWrappedFunctionNames: false -InsertTrailingCommas: None -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true -LambdaBodyIndentation: Signature -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: Inner -ObjCBinPackProtocolList: Auto -ObjCBlockIndentWidth: 2 -ObjCBreakBeforeNestedBlockParam: true -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakOpenParenthesis: 0 -PenaltyBreakString: 1000 -PenaltyBreakTemplateDeclaration: 10 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 1000 -PenaltyIndentedWhitespace: 0 -PointerAlignment: Left -PPIndentWidth: -1 -ReferenceAlignment: Pointer -ReflowComments: true -RemoveBracesLLVM: false -RequiresClausePosition: OwnLine -SeparateDefinitionBlocks: Leave -ShortNamespaceLines: 50 -SortIncludes: CaseSensitive -SortJavaStaticImport: Before -SortUsingDeclarations: true -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeCaseColon: false -SpaceBeforeCpp11BracedList: true -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeParensOptions: - AfterControlStatements: true - AfterForeachMacros: true - AfterFunctionDefinitionName: false - AfterFunctionDeclarationName: false - AfterIfMacros: true - AfterOverloadedOperator: false - AfterRequiresInClause: true - AfterRequiresInExpression: true - BeforeNonEmptyParentheses: false -SpaceAroundPointerQualifiers: Default -SpaceBeforeRangeBasedForLoopColon: true -SpaceInEmptyBlock: false -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: Never -SpacesInConditionalStatement: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInLineCommentPrefix: - Minimum: 1 - Maximum: -1 -SpacesInParentheses: false -SpacesInSquareBrackets: false -SpaceBeforeSquareBrackets: false -BitFieldColonSpacing: Both -Standard: c++20 -StatementAttributeLikeMacros: - - Q_EMIT -StatementMacros: - - Q_UNUSED - - QT_REQUIRE_VERSION -TabWidth: 4 -UseCRLF: false -UseTab: Never -WhitespaceSensitiveMacros: - - STRINGIZE - - PP_STRINGIZE - - BOOST_PP_STRINGIZE - - NS_SWIFT_NAME - - CF_SWIFT_NAME diff --git a/source/cli/meojson/bitops.hpp b/source/cli/meojson/bitops.hpp deleted file mode 100644 index ec6137f..0000000 --- a/source/cli/meojson/bitops.hpp +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) -#include -namespace json::__bitops { - using std::countl_one; - using std::countr_one; - using std::countl_zero; - using std::countr_zero; - inline constexpr bool is_little_endian() { - return std::endian::native == std::endian::little; - } -} -#else -#include -namespace json::__bitops { -#if defined(__GNUC__) || defined(__clang__) - inline constexpr int countl_zero(uint32_t x) { - if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) - return x == 0 ? 32 : __builtin_clz(x); - if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) - return x == 0 ? 32 : __builtin_clzl(x); - return x == 0 ? 32 : __builtin_clzll(x); - } - inline constexpr int countr_zero(uint32_t x) { - if constexpr (sizeof(uint32_t) == sizeof(unsigned int)) - return x == 0 ? 32 : __builtin_ctz(x); - if constexpr (sizeof(uint32_t) == sizeof(unsigned long)) - return x == 0 ? 32 : __builtin_ctzl(x); - return x == 0 ? 32 : __builtin_ctzll(x); - } - inline constexpr int countl_zero(uint64_t x) { - return x == 0 ? 64 : __builtin_clzll(x); - } - inline constexpr int countr_zero(uint64_t x) { - return x == 0 ? 64 : __builtin_ctzll(x); - } -#elif defined(_MSC_VER) -#ifdef __AVX2__ - // lzcnt intrinsics is not constexpr - inline int countl_zero(uint32_t x) { - return __lzcnt(x); - } - inline int countr_zero(uint32_t x) { - return _tzcnt_u32(x); - } - inline int countl_zero(uint64_t x) { - return (int)__lzcnt64(x); - } - inline int countr_zero(uint64_t x) { - return (int)_tzcnt_u64(x); - } -#else - inline constexpr int countl_zero(uint32_t x) { - unsigned long index = 0; - return _BitScanReverse(&index, x) ? 31 - index : 32; - } - inline constexpr int countr_zero(uint32_t x) { - unsigned long index = 0; - return _BitScanForward(&index, x) ? index : 32; - } - inline constexpr int countl_zero(uint64_t x) { - unsigned long index = 0; - return _BitScanReverse64(&index, x) ? 63 - index : 64; - } - inline constexpr int countr_zero(uint64_t x) { - unsigned long index = 0; - return _BitScanForward64(&index, x) ? index : 64; - } -#endif // __AVX2__ -#else // compiler -#error "bring your own bit counting implementation" -#endif - inline int countl_one(uint32_t x) { return countl_zero(~x); } - inline int countr_one(uint32_t x) { return countr_zero(~x); } - inline int countl_one(uint64_t x) { return countl_zero(~x); } - inline int countr_one(uint64_t x) { return countr_zero(~x); } - - // no constexpr endian awareness before C++20 - inline bool is_little_endian() { - union { - uint32_t u32; - uint8_t u8; - } u = { 0x01020304 }; - return u.u8 == 4; - } -} -#endif // C++20 diff --git a/source/cli/meojson/json.hpp b/source/cli/meojson/json.hpp deleted file mode 100644 index aed9618..0000000 --- a/source/cli/meojson/json.hpp +++ /dev/null @@ -1,2669 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "packed_bytes.hpp" - -#define MEOJSON_INLINE inline - -namespace json -{ -template -class basic_value; -template -class basic_array; -template -class basic_object; - -using default_string_t = std::string; - -using value = basic_value; -using array = basic_array; -using object = basic_object; - -using wvalue = basic_value; -using warray = basic_array; -using wobject = basic_object; - -using u16value = basic_value; -using u16array = basic_array; -using u16object = basic_object; - -using u32value = basic_value; -using u32array = basic_array; -using u32object = basic_object; - -// ********************************* -// * basic_value declare * -// ********************************* - -template -class basic_value -{ - using array_ptr = std::unique_ptr>; - using object_ptr = std::unique_ptr>; - -public: - enum class value_type : char - { - invalid, - null, - boolean, - string, - number, - array, - object - }; - - using var_t = std::variant; - using char_t = typename string_t::value_type; - -public: - basic_value(); - basic_value(const basic_value& rhs); - basic_value(basic_value&& rhs) noexcept; - - basic_value(bool b); - - basic_value(int num); - basic_value(unsigned num); - basic_value(long num); - basic_value(unsigned long num); - basic_value(long long num); - basic_value(unsigned long long num); - basic_value(float num); - basic_value(double num); - basic_value(long double num); - - basic_value(const char_t* str); - basic_value(string_t str); - - basic_value(basic_array arr); - basic_value(basic_object obj); - basic_value(std::initializer_list>> init_list); - - // Constructed from raw data - template - basic_value(value_type type, args_t&&... args); - - // Prohibit conversion of other types to basic_value - template - basic_value(value_t) = delete; - - ~basic_value(); - - bool valid() const noexcept { return _type != value_type::invalid; } - bool empty() const noexcept { return is_null(); } - bool is_null() const noexcept { return _type == value_type::null; } - bool is_number() const noexcept { return _type == value_type::number; } - bool is_boolean() const noexcept { return _type == value_type::boolean; } - bool is_string() const noexcept { return _type == value_type::string; } - bool is_array() const noexcept { return _type == value_type::array; } - bool is_object() const noexcept { return _type == value_type::object; } - template - bool is() const noexcept; - - bool contains(const string_t& key) const; - bool contains(size_t pos) const; - bool exists(const string_t& key) const { return contains(key); } - bool exists(size_t pos) const { return contains(pos); } - value_type type() const noexcept { return _type; } - const basic_value& at(size_t pos) const; - const basic_value& at(const string_t& key) const; - - bool erase(size_t pos); - bool erase(const string_t& key); - - // Usage: get(key_1, key_2, ..., default_value); - template - auto get(key_then_default_value_t&&... keys_then_default_value) const; - - template > - std::optional find(size_t pos) const; - template > - std::optional find(const string_t& key) const; - - bool as_boolean() const; - int as_integer() const; - unsigned as_unsigned() const; - long as_long() const; - unsigned long as_unsigned_long() const; - long long as_long_long() const; - unsigned long long as_unsigned_long_long() const; - float as_float() const; - double as_double() const; - long double as_long_double() const; - string_t as_string() const; - const basic_array& as_array() const; - const basic_object& as_object() const; - template - value_t as() const; - - basic_array& as_array(); - basic_object& as_object(); - - template - decltype(auto) emplace(args_t&&... args); - - template - /*will be deprecated, please use `emplace` instead.*/ - decltype(auto) array_emplace(args_t&&... args); - template - /*will be deprecated, please use `emplace` instead.*/ - decltype(auto) object_emplace(args_t&&... args); - - void clear() noexcept; - - string_t dumps(std::optional indent = std::nullopt) const { return indent ? format(*indent) : to_string(); } - // return raw string - string_t to_string() const; - string_t format() const { return format(4, 0); } - // format(bool) is deprecated now. - template && !std::is_same_v>> - string_t format(sz_t indent) const - { - return format(indent, 0); - } - - basic_value& operator=(const basic_value& rhs); - basic_value& operator=(basic_value&&) noexcept; - - bool operator==(const basic_value& rhs) const; - bool operator!=(const basic_value& rhs) const { return !(*this == rhs); } - - const basic_value& operator[](size_t pos) const; - basic_value& operator[](size_t pos); - basic_value& operator[](const string_t& key); - basic_value& operator[](string_t&& key); - - basic_value operator|(const basic_object& rhs) const&; - basic_value operator|(basic_object&& rhs) const&; - basic_value operator|(const basic_object& rhs) &&; - basic_value operator|(basic_object&& rhs) &&; - - basic_value& operator|=(const basic_object& rhs); - basic_value& operator|=(basic_object&& rhs); - - basic_value operator+(const basic_array& rhs) const&; - basic_value operator+(basic_array&& rhs) const&; - basic_value operator+(const basic_array& rhs) &&; - basic_value operator+(basic_array&& rhs) &&; - - basic_value& operator+=(const basic_array& rhs); - basic_value& operator+=(basic_array&& rhs); - - explicit operator bool() const { return as_boolean(); } - explicit operator int() const { return as_integer(); } - explicit operator unsigned() const { return as_unsigned(); } - explicit operator long() const { return as_long(); } - explicit operator unsigned long() const { return as_unsigned_long(); } - explicit operator long long() const { return as_long_long(); } - explicit operator unsigned long long() const { return as_unsigned_long_long(); } - explicit operator float() const { return as_float(); } - explicit operator double() const { return as_double(); } - explicit operator long double() const { return as_long_double(); } - explicit operator string_t() const { return as_string(); } - -private: - friend class basic_array; - friend class basic_object; - - string_t format(size_t indent, size_t indent_times) const; - - static var_t deep_copy(const var_t& src); - - template - auto get(std::tuple keys_then_default_value, - std::index_sequence) const; - - template - auto get_helper(const value_t& default_value, first_key_t&& first, rest_keys_t&&... rest) const; - template - auto get_helper(const value_t& default_value, unique_key_t&& first) const; - - const string_t& as_basic_type_str() const; - string_t& as_basic_type_str(); - - value_type _type = value_type::null; - var_t _raw_data; -}; - -// ********************************* -// * basic_array declare * -// ********************************* - -template -class basic_array -{ - friend class basic_value; - friend class basic_object; - -public: - using raw_array = std::vector>; - using value_type = typename raw_array::value_type; - using iterator = typename raw_array::iterator; - using const_iterator = typename raw_array::const_iterator; - using reverse_iterator = typename raw_array::reverse_iterator; - using const_reverse_iterator = typename raw_array::const_reverse_iterator; - using char_t = typename string_t::value_type; - -public: - basic_array() = default; - basic_array(const basic_array& rhs) = default; - basic_array(basic_array&& rhs) noexcept = default; - basic_array(const raw_array& arr); - basic_array(raw_array&& arr) noexcept; - basic_array(std::initializer_list init_list); - basic_array(typename raw_array::size_type size); - - explicit basic_array(const basic_value& val); - explicit basic_array(basic_value&& val); - template ::value_type>>> - basic_array(array_t arr) - { - _array_data.assign(std::make_move_iterator(arr.begin()), std::make_move_iterator(arr.end())); - } - - ~basic_array() noexcept = default; - - bool empty() const noexcept { return _array_data.empty(); } - size_t size() const noexcept { return _array_data.size(); } - bool contains(size_t pos) const { return pos < _array_data.size(); } - bool exists(size_t pos) const { return contains(pos); } - const basic_value& at(size_t pos) const; - - string_t dumps(std::optional indent = std::nullopt) const { return indent ? format(*indent) : to_string(); } - string_t to_string() const; - string_t format() const { return format(4, 0); } - template && !std::is_same_v>> - string_t format(sz_t indent) const - { - return format(indent, 0); - } - - // Usage: get(key_1, key_2, ..., default_value); - template - auto get(key_then_default_value_t&&... keys_then_default_value) const; - - template > - std::optional find(size_t pos) const; - - template - decltype(auto) emplace_back(args_t&&... args); - template - decltype(auto) push_back(args_t&&... args); - - void clear() noexcept; - bool erase(size_t pos); - - iterator begin() noexcept; - iterator end() noexcept; - const_iterator begin() const noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - - reverse_iterator rbegin() noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rbegin() const noexcept; - const_reverse_iterator rend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; - - const basic_value& operator[](size_t pos) const; - basic_value& operator[](size_t pos); - - basic_array operator+(const basic_array& rhs) const&; - basic_array operator+(basic_array&& rhs) const&; - basic_array operator+(const basic_array& rhs) &&; - basic_array operator+(basic_array&& rhs) &&; - - basic_array& operator+=(const basic_array& rhs); - basic_array& operator+=(basic_array&& rhs); - - basic_array& operator=(const basic_array&) = default; - basic_array& operator=(basic_array&&) noexcept = default; - - bool operator==(const basic_array& rhs) const; - bool operator!=(const basic_array& rhs) const { return !(*this == rhs); } - -private: - template - auto get(std::tuple keys_then_default_value, - std::index_sequence) const; - template - auto get_helper(const value_t& default_value, size_t pos, rest_keys_t&&... rest) const; - template - auto get_helper(const value_t& default_value, size_t pos) const; - - string_t format(size_t indent, size_t indent_times) const; - -private: - raw_array _array_data; -}; - -// ********************************** -// * basic_object declare * -// ********************************** - -template -class basic_object -{ - friend class basic_value; - friend class basic_array; - -public: - using raw_object = std::map>; - using key_type = typename raw_object::key_type; - using mapped_type = typename raw_object::mapped_type; - using value_type = typename raw_object::value_type; - using iterator = typename raw_object::iterator; - using const_iterator = typename raw_object::const_iterator; - using char_t = typename string_t::value_type; - -public: - basic_object() = default; - basic_object(const basic_object& rhs) = default; - basic_object(basic_object&& rhs) noexcept = default; - basic_object(const raw_object& raw_obj); - basic_object(raw_object&& raw_obj); - basic_object(std::initializer_list init_list); - explicit basic_object(const basic_value& val); - explicit basic_object(basic_value&& val); - template ::value_type>>> - basic_object(map_t map) - { - _object_data.insert(std::make_move_iterator(map.begin()), std::make_move_iterator(map.end())); - } - - ~basic_object() = default; - - bool empty() const noexcept { return _object_data.empty(); } - size_t size() const noexcept { return _object_data.size(); } - bool contains(const string_t& key) const; - bool exists(const string_t& key) const { return contains(key); } - const basic_value& at(const string_t& key) const; - - string_t dumps(std::optional indent = std::nullopt) const { return indent ? format(*indent) : to_string(); } - string_t to_string() const; - string_t format() const { return format(4, 0); } - template && !std::is_same_v>> - string_t format(sz_t indent) const - { - return format(indent, 0); - } - - // Usage: get(key_1, key_2, ..., default_value); - template - auto get(key_then_default_value_t&&... keys_then_default_value) const; - - template > - std::optional find(const string_t& key) const; - - template - decltype(auto) emplace(args_t&&... args); - template - decltype(auto) insert(args_t&&... args); - - void clear() noexcept; - bool erase(const string_t& key); - - iterator begin() noexcept; - iterator end() noexcept; - const_iterator begin() const noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - - basic_value& operator[](const string_t& key); - basic_value& operator[](string_t&& key); - - basic_object operator|(const basic_object& rhs) const&; - basic_object operator|(basic_object&& rhs) const&; - basic_object operator|(const basic_object& rhs) &&; - basic_object operator|(basic_object&& rhs) &&; - - basic_object& operator|=(const basic_object& rhs); - basic_object& operator|=(basic_object&& rhs); - - basic_object& operator=(const basic_object&) = default; - basic_object& operator=(basic_object&&) = default; - - bool operator==(const basic_object& rhs) const; - bool operator!=(const basic_object& rhs) const { return !(*this == rhs); } - -private: - template - auto get(std::tuple keys_then_default_value, - std::index_sequence) const; - template - auto get_helper(const value_t& default_value, const string_t& key, rest_keys_t&&... rest) const; - template - auto get_helper(const value_t& default_value, const string_t& key) const; - - string_t format(size_t indent, size_t indent_times) const; - -private: - raw_object _object_data; -}; - -// **************************** -// * parser declare * -// **************************** - -template -class parser -{ -public: - using parsing_iter_t = typename parsing_t::const_iterator; - -public: - ~parser() noexcept = default; - - static std::optional> parse(const parsing_t& content); - -private: - parser(parsing_iter_t cbegin, parsing_iter_t cend) noexcept : _cur(cbegin), _end(cend) { ; } - - std::optional> parse(); - basic_value parse_value(); - - basic_value parse_null(); - basic_value parse_boolean(); - basic_value parse_number(); - // parse and return a basic_value whose type is value_type::string - basic_value parse_string(); - basic_value parse_array(); - basic_value parse_object(); - - // parse and return a string_t - std::optional parse_stdstring(); - - void skip_string_literal(); - bool skip_whitespace() noexcept; - bool skip_digit(); - -private: - parsing_iter_t _cur; - parsing_iter_t _end; -}; - -// ******************************* -// * exception declare * -// ******************************* - -class exception : public std::exception -{ -public: - exception() = default; - exception(const std::string& msg) : _what(msg) {} - - exception(const exception&) = default; - exception& operator=(const exception&) = default; - exception(exception&&) = default; - exception& operator=(exception&&) = default; - - virtual ~exception() noexcept override = default; - - virtual const char* what() const noexcept override { return _what.empty() ? "Unknown exception" : _what.c_str(); } - -protected: - std::string _what; -}; - -// *************************** -// * utils declare * -// *************************** - -template -auto parse(const parsing_t& content); -template , istream_t>>> -auto parse(istream_t& istream, bool check_bom); - -template -auto open(const path_t& path, bool check_bom = false); - -namespace literals -{ - value operator""_json(const char* str, size_t len); - wvalue operator""_json(const wchar_t* str, size_t len); - u16value operator""_json(const char16_t* str, size_t len); - u32value operator""_json(const char32_t* str, size_t len); - - value operator""_jvalue(const char* str, size_t len); - wvalue operator""_jvalue(const wchar_t* str, size_t len); - u16value operator""_jvalue(const char16_t* str, size_t len); - u32value operator""_jvalue(const char32_t* str, size_t len); - - array operator""_jarray(const char* str, size_t len); - warray operator""_jarray(const wchar_t* str, size_t len); - u16array operator""_jarray(const char16_t* str, size_t len); - u32array operator""_jarray(const char32_t* str, size_t len); - - object operator""_jobject(const char* str, size_t len); - wobject operator""_jobject(const wchar_t* str, size_t len); - u16object operator""_jobject(const char16_t* str, size_t len); - u32object operator""_jobject(const char32_t* str, size_t len); -} - -template -const basic_value invalid_value(); - -template -basic_value serialize(any_t&& arg); - -// ****************************** -// * basic_value impl * -// ****************************** - -template -static constexpr string_t true_string() -{ - return { 't', 'r', 'u', 'e' }; -} - -template -static constexpr string_t false_string() -{ - return { 'f', 'a', 'l', 's', 'e' }; -} - -template -static constexpr string_t null_string() -{ - return { 'n', 'u', 'l', 'l' }; -} - -template -static constexpr string_t unescape_string(const string_t& str); - -template -MEOJSON_INLINE basic_value::basic_value() = default; - -template -MEOJSON_INLINE basic_value::basic_value(const basic_value& rhs) - : _type(rhs._type), _raw_data(deep_copy(rhs._raw_data)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(basic_value&& rhs) noexcept = default; - -template -MEOJSON_INLINE basic_value::basic_value(bool b) - : _type(value_type::boolean), _raw_data(string_t(b ? true_string() : false_string())) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(int num) : _type(value_type::number), _raw_data(std::to_string(num)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(unsigned num) - : _type(value_type::number), _raw_data(std::to_string(num)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(long num) : _type(value_type::number), _raw_data(std::to_string(num)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(unsigned long num) - : _type(value_type::number), _raw_data(std::to_string(num)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(long long num) - : _type(value_type::number), _raw_data(std::to_string(num)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(unsigned long long num) - : _type(value_type::number), _raw_data(std::to_string(num)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(float num) : _type(value_type::number), _raw_data(std::to_string(num)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(double num) - : _type(value_type::number), _raw_data(std::to_string(num)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(long double num) - : _type(value_type::number), _raw_data(std::to_string(num)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(const char_t* str) - : _type(value_type::string), _raw_data(string_t(str)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(string_t str) : _type(value_type::string), _raw_data(std::move(str)) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(basic_array arr) - : _type(value_type::array), _raw_data(std::make_unique>(std::move(arr))) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value(basic_object obj) - : _type(value_type::object), _raw_data(std::make_unique>(std::move(obj))) -{ - ; -} - -template -MEOJSON_INLINE basic_value::basic_value( - std::initializer_list>> init_list) - : _type(value_type::object), _raw_data(std::make_unique>(init_list)) -{ - ; -} - -// for Pimpl -template -MEOJSON_INLINE basic_value::~basic_value() = default; - -template -template -MEOJSON_INLINE bool basic_value::is() const noexcept -{ - if constexpr (std::is_same_v, value_t>) { - return true; - } - else if constexpr (std::is_same_v) { - return _type == value_type::boolean; - } - else if constexpr (std::is_arithmetic_v) { - return _type == value_type::number; - } - else if constexpr (std::is_same_v, value_t>) { - return _type == value_type::array; - } - else if constexpr (std::is_same_v, value_t>) { - return _type == value_type::object; - } - else if constexpr (std::is_constructible_v) { - return _type == value_type::string; - } - else { - static_assert(!sizeof(value_t), "Unsupported type"); - } -} - -template -MEOJSON_INLINE bool basic_value::contains(const string_t& key) const -{ - return is_object() && as_object().contains(key); -} - -template -MEOJSON_INLINE bool basic_value::contains(size_t pos) const -{ - return is_array() && as_array().contains(pos); -} - -template -MEOJSON_INLINE const basic_value& basic_value::at(size_t pos) const -{ - return as_array().at(pos); -} - -template -MEOJSON_INLINE const basic_value& basic_value::at(const string_t& key) const -{ - return as_object().at(key); -} - -template -MEOJSON_INLINE bool basic_value::erase(size_t pos) -{ - return as_array().erase(pos); -} - -template -MEOJSON_INLINE bool basic_value::erase(const string_t& key) -{ - return as_object().erase(key); -} - -template -template -MEOJSON_INLINE auto basic_value::get(key_then_default_value_t&&... keys_then_default_value) const -{ - return get(std::forward_as_tuple(keys_then_default_value...), - std::make_index_sequence {}); -} - -template -template -MEOJSON_INLINE auto basic_value::get(std::tuple keys_then_default_value, - std::index_sequence) const -{ - constexpr unsigned long default_value_index = sizeof...(key_then_default_value_t) - 1; - return get_helper(std::get(keys_then_default_value), - std::get(keys_then_default_value)...); -} - -template -template -MEOJSON_INLINE auto basic_value::get_helper(const value_t& default_value, first_key_t&& first, - rest_keys_t&&... rest) const -{ - if constexpr (std::is_constructible_v) { - return is_object() ? as_object().get_helper(default_value, std::forward(first), - std::forward(rest)...) - : default_value; - } - else if constexpr (std::is_integral_v>) { - return is_array() ? as_array().get_helper(default_value, std::forward(first), - std::forward(rest)...) - : default_value; - } - else { - static_assert(!sizeof(first_key_t), "Parameter must be integral or string_t constructible"); - } -} - -template -template -MEOJSON_INLINE auto basic_value::get_helper(const value_t& default_value, unique_key_t&& first) const -{ - if constexpr (std::is_constructible_v) { - return is_object() ? as_object().get_helper(default_value, std::forward(first)) : default_value; - } - else if constexpr (std::is_integral_v>) { - return is_array() ? as_array().get_helper(default_value, std::forward(first)) : default_value; - } - else { - static_assert(!sizeof(unique_key_t), "Parameter must be integral or string_t constructible"); - } -} - -template -template -MEOJSON_INLINE auto basic_array::get(key_then_default_value_t&&... keys_then_default_value) const -{ - return get(std::forward_as_tuple(keys_then_default_value...), - std::make_index_sequence {}); -} - -template -template -MEOJSON_INLINE auto basic_array::get(std::tuple keys_then_default_value, - std::index_sequence) const -{ - constexpr unsigned long default_value_index = sizeof...(key_then_default_value_t) - 1; - return get_helper(std::get(keys_then_default_value), - std::get(keys_then_default_value)...); -} - -template -template -MEOJSON_INLINE auto basic_object::get(key_then_default_value_t&&... keys_then_default_value) const -{ - return get(std::forward_as_tuple(keys_then_default_value...), - std::make_index_sequence {}); -} - -template -template -MEOJSON_INLINE auto basic_object::get(std::tuple keys_then_default_value, - std::index_sequence) const -{ - constexpr unsigned long default_value_index = sizeof...(key_then_default_value_t) - 1; - return get_helper(std::get(keys_then_default_value), - std::get(keys_then_default_value)...); -} - -template -template -MEOJSON_INLINE std::optional basic_value::find(size_t pos) const -{ - return is_array() ? as_array().template find(pos) : std::nullopt; -} - -template -template -MEOJSON_INLINE std::optional basic_value::find(const string_t& key) const -{ - return is_object() ? as_object().template find(key) : std::nullopt; -} - -template -MEOJSON_INLINE bool basic_value::as_boolean() const -{ - if (is_boolean()) { - if (const string_t& b_str = as_basic_type_str(); b_str == true_string()) { - return true; - } - else if (b_str == false_string()) { - return false; - } - else { - throw exception("Unknown Parse Error"); - } - } - else { - throw exception("Wrong Type"); - } -} - -template -MEOJSON_INLINE int basic_value::as_integer() const -{ - if (is_number()) { - return std::stoi(as_basic_type_str()); - } - else { - throw exception("Wrong Type"); - } -} - -template -MEOJSON_INLINE unsigned basic_value::as_unsigned() const -{ - // I don't know why there is no std::stou. - return static_cast(as_unsigned_long()); -} - -template -MEOJSON_INLINE long basic_value::as_long() const -{ - if (is_number()) { - return std::stol(as_basic_type_str()); - } - else { - throw exception("Wrong Type"); - } -} - -template -MEOJSON_INLINE unsigned long basic_value::as_unsigned_long() const -{ - if (is_number()) { - return std::stoul(as_basic_type_str()); - } - else { - throw exception("Wrong Type"); - } -} - -template -MEOJSON_INLINE long long basic_value::as_long_long() const -{ - if (is_number()) { - return std::stoll(as_basic_type_str()); - } - else { - throw exception("Wrong Type"); - } -} - -template -MEOJSON_INLINE unsigned long long basic_value::as_unsigned_long_long() const -{ - if (is_number()) { - return std::stoull(as_basic_type_str()); - } - else { - throw exception("Wrong Type"); - } -} - -template -MEOJSON_INLINE float basic_value::as_float() const -{ - if (is_number()) { - return std::stof(as_basic_type_str()); - } - else { - throw exception("Wrong Type"); - } -} - -template -MEOJSON_INLINE double basic_value::as_double() const -{ - if (is_number()) { - return std::stod(as_basic_type_str()); - } - else { - throw exception("Wrong Type"); - } -} - -template -MEOJSON_INLINE long double basic_value::as_long_double() const -{ - if (is_number()) { - return std::stold(as_basic_type_str()); - } - else { - throw exception("Wrong Type"); - } -} - -template -MEOJSON_INLINE string_t basic_value::as_string() const -{ - if (is_string()) { - return as_basic_type_str(); - } - else { - throw exception("Wrong Type"); - } -} - -template -MEOJSON_INLINE const basic_array& basic_value::as_array() const -{ - if (is_array()) { - return *std::get(_raw_data); - } - - throw exception("Wrong Type"); -} - -template -MEOJSON_INLINE const basic_object& basic_value::as_object() const -{ - if (is_object()) { - return *std::get(_raw_data); - } - - throw exception("Wrong Type or data empty"); -} - -template -MEOJSON_INLINE basic_array& basic_value::as_array() -{ - if (empty()) { - *this = basic_array(); - } - - if (is_array()) { - return *std::get(_raw_data); - } - - throw exception("Wrong Type"); -} - -template -MEOJSON_INLINE basic_object& basic_value::as_object() -{ - if (empty()) { - *this = basic_object(); - } - - if (is_object()) { - return *std::get(_raw_data); - } - - throw exception("Wrong Type or data empty"); -} - -template -template -MEOJSON_INLINE value_t basic_value::as() const -{ - return static_cast(*this); -} - -template -MEOJSON_INLINE const string_t& basic_value::as_basic_type_str() const -{ - return std::get(_raw_data); -} - -template -MEOJSON_INLINE string_t& basic_value::as_basic_type_str() -{ - return std::get(_raw_data); -} - -template -template -MEOJSON_INLINE decltype(auto) basic_value::emplace(args_t&&... args) -{ - constexpr bool is_array_args = std::is_constructible_v::value_type, args_t...>; - constexpr bool is_object_args = std::is_constructible_v::value_type, args_t...>; - - static_assert(is_array_args || is_object_args, "Args can not constructure a array or object value"); - - if constexpr (is_array_args) { - return as_array().emplace_back(std::forward(args)...); - } - else if constexpr (is_object_args) { - return as_object().emplace(std::forward(args)...); - } -} - -template -template -MEOJSON_INLINE decltype(auto) basic_value::array_emplace(args_t&&... args) -{ - return emplace(std::forward(args)...); -} - -template -template -MEOJSON_INLINE decltype(auto) basic_value::object_emplace(args_t&&... args) -{ - return emplace(std::forward(args)...); -} - -template -MEOJSON_INLINE void basic_value::clear() noexcept -{ - *this = basic_value(); -} - -template -MEOJSON_INLINE string_t basic_value::to_string() const -{ - switch (_type) { - case value_type::null: - return null_string(); - case value_type::boolean: - case value_type::number: - return as_basic_type_str(); - case value_type::string: - return char_t('"') + unescape_string(as_basic_type_str()) + char_t('"'); - case value_type::array: - return as_array().to_string(); - case value_type::object: - return as_object().to_string(); - default: - throw exception("Unknown basic_value Type"); - } -} - -template -MEOJSON_INLINE string_t basic_value::format(size_t indent, size_t indent_times) const -{ - switch (_type) { - case value_type::null: - case value_type::boolean: - case value_type::number: - case value_type::string: - return to_string(); - case value_type::array: - return as_array().format(indent, indent_times); - case value_type::object: - return as_object().format(indent, indent_times); - default: - throw exception("Unknown basic_value Type"); - } -} - -template -MEOJSON_INLINE basic_value& basic_value::operator=(const basic_value& rhs) -{ - _type = rhs._type; - _raw_data = deep_copy(rhs._raw_data); - - return *this; -} - -template -MEOJSON_INLINE basic_value& basic_value::operator=(basic_value&& rhs) noexcept = default; - -template -MEOJSON_INLINE bool basic_value::operator==(const basic_value& rhs) const -{ - if (_type != rhs._type) return false; - - switch (_type) { - case value_type::null: - return rhs.is_null(); - case value_type::boolean: - case value_type::number: - case value_type::string: - return _raw_data == rhs._raw_data; - case value_type::array: - return as_array() == rhs.as_array(); - case value_type::object: - return as_object() == rhs.as_object(); - default: - throw exception("Unknown basic_value Type"); - } -} - -template -MEOJSON_INLINE const basic_value& basic_value::operator[](size_t pos) const -{ - // basic_array not support to create by operator[] - - return as_array()[pos]; -} - -template -MEOJSON_INLINE basic_value& basic_value::operator[](size_t pos) -{ - // basic_array not support to create by operator[] - - return as_array()[pos]; -} - -template -MEOJSON_INLINE basic_value& basic_value::operator[](const string_t& key) -{ - if (empty()) { - *this = basic_object(); - } - - return as_object()[key]; -} - -template -MEOJSON_INLINE basic_value& basic_value::operator[](string_t&& key) -{ - if (empty()) { - *this = basic_object(); - } - - return as_object()[std::move(key)]; -} - -template -MEOJSON_INLINE basic_value basic_value::operator|(const basic_object& rhs) const& -{ - return as_object() | rhs; -} - -template -MEOJSON_INLINE basic_value basic_value::operator|(basic_object&& rhs) const& -{ - return as_object() | std::move(rhs); -} - -template -MEOJSON_INLINE basic_value basic_value::operator|(const basic_object& rhs) && -{ - return std::move(as_object()) | rhs; -} - -template -MEOJSON_INLINE basic_value basic_value::operator|(basic_object&& rhs) && -{ - return std::move(as_object()) | std::move(rhs); -} - -template -MEOJSON_INLINE basic_value& basic_value::operator|=(const basic_object& rhs) -{ - as_object() |= rhs; - return *this; -} - -template -MEOJSON_INLINE basic_value& basic_value::operator|=(basic_object&& rhs) -{ - as_object() |= std::move(rhs); - return *this; -} - -template -MEOJSON_INLINE basic_value basic_value::operator+(const basic_array& rhs) const& -{ - return as_array() + rhs; -} - -template -MEOJSON_INLINE basic_value basic_value::operator+(basic_array&& rhs) const& -{ - return as_array() + std::move(rhs); -} - -template -MEOJSON_INLINE basic_value basic_value::operator+(const basic_array& rhs) && -{ - return std::move(as_array()) + rhs; -} - -template -MEOJSON_INLINE basic_value basic_value::operator+(basic_array&& rhs) && -{ - return std::move(as_array()) + std::move(rhs); -} - -template -MEOJSON_INLINE basic_value& basic_value::operator+=(const basic_array& rhs) -{ - as_array() += rhs; - return *this; -} - -template -MEOJSON_INLINE basic_value& basic_value::operator+=(basic_array&& rhs) -{ - as_array() += std::move(rhs); - return *this; -} - -template -template -basic_value::basic_value(value_type type, args_t&&... args) - : _type(type), _raw_data(std::forward(args)...) -{ - static_assert(std::is_constructible_v, "Parameter can't be used to construct a var_t"); -} - -template -MEOJSON_INLINE typename basic_value::var_t basic_value::deep_copy(const var_t& src) -{ - var_t dst; - if (const auto string_ptr = std::get_if(&src)) { - dst = *string_ptr; - } - else if (const auto arr_ptr = std::get_if(&src)) { - dst = std::make_unique>(**arr_ptr); - } - else if (const auto obj_ptr = std::get_if(&src)) { - dst = std::make_unique>(**obj_ptr); - } - else { - // maybe invalid_value - } - - return dst; -} - -// ****************************** -// * basic_array impl * -// ****************************** - -template -MEOJSON_INLINE basic_array::basic_array(const raw_array& arr) : _array_data(arr) -{ - ; -} - -template -MEOJSON_INLINE basic_array::basic_array(raw_array&& arr) noexcept : _array_data(std::move(arr)) -{ - ; -} - -template -MEOJSON_INLINE basic_array::basic_array(std::initializer_list init_list) : _array_data(init_list) -{ - ; -} - -template -MEOJSON_INLINE basic_array::basic_array(typename raw_array::size_type size) : _array_data(size) -{ - ; -} - -template -MEOJSON_INLINE basic_array::basic_array(const basic_value& val) - : basic_array(val.as_array()) -{ - ; -} - -template -MEOJSON_INLINE basic_array::basic_array(basic_value&& val) - : basic_array(std::move(val.as_array())) -{ - ; -} - -template -MEOJSON_INLINE void basic_array::clear() noexcept -{ - _array_data.clear(); -} - -template -MEOJSON_INLINE bool basic_array::erase(size_t pos) -{ - return _array_data.erase(pos) != _array_data.end(); -} - -template -template -MEOJSON_INLINE decltype(auto) basic_array::emplace_back(args_t&&... args) -{ - static_assert(std::is_constructible_v, - "Parameter can't be used to construct a raw_array::value_type"); - return _array_data.emplace_back(std::forward(args)...); -} - -template -template -MEOJSON_INLINE decltype(auto) basic_array::push_back(args_t&&... args) -{ - return emplace_back(std::forward(args)...); -} - -template -MEOJSON_INLINE const basic_value& basic_array::at(size_t pos) const -{ - return _array_data.at(pos); -} - -template -MEOJSON_INLINE string_t basic_array::to_string() const -{ - string_t str { '[' }; - for (auto iter = _array_data.cbegin(); iter != _array_data.cend();) { - str += iter->to_string(); - if (++iter != _array_data.cend()) { - str += ','; - } - } - str += char_t(']'); - return str; -} - -template -MEOJSON_INLINE string_t basic_array::format(size_t indent, size_t indent_times) const -{ - const string_t tail_indent(indent * indent_times, ' '); - const string_t body_indent(indent * (indent_times + 1), ' '); - - string_t str { '[', '\n' }; - for (auto iter = _array_data.cbegin(); iter != _array_data.cend();) { - str += body_indent + iter->format(indent, indent_times + 1); - if (++iter != _array_data.cend()) { - str += ','; - } - str += '\n'; - } - str += tail_indent + char_t(']'); - return str; -} - -template -template -MEOJSON_INLINE auto basic_array::get_helper(const value_t& default_value, size_t pos, - rest_keys_t&&... rest) const -{ - constexpr bool is_json = std::is_same_v, value_t> || - std::is_same_v, value_t> || - std::is_same_v, value_t>; - constexpr bool is_string = std::is_constructible_v && !is_json; - - if (!contains(pos)) { - if constexpr (is_string) { - return string_t(default_value); - } - else { - return value_t(default_value); - } - } - - return at(pos).get_helper(default_value, std::forward(rest)...); -} - -template -template -MEOJSON_INLINE auto basic_array::get_helper(const value_t& default_value, size_t pos) const -{ - constexpr bool is_json = std::is_same_v, value_t> || - std::is_same_v, value_t> || - std::is_same_v, value_t>; - constexpr bool is_string = std::is_constructible_v && !is_json; - - if (!contains(pos)) { - if constexpr (is_string) { - return string_t(default_value); - } - else { - return value_t(default_value); - } - } - - auto val = _array_data.at(pos); - if (val.template is()) { - if constexpr (is_string) { - return val.template as(); - } - else { - return val.template as(); - } - } - else { - if constexpr (is_string) { - return string_t(default_value); - } - else { - return value_t(default_value); - } - } -} - -template -template -MEOJSON_INLINE std::optional basic_array::find(size_t pos) const -{ - static_assert(std::is_constructible_v>, - "Type can NOT be constructed by basic_value"); - if (!contains(pos)) { - return std::nullopt; - } - const auto& val = _array_data.at(pos); - return val.template is() ? std::optional(val.template as()) : std::nullopt; -} - -template -MEOJSON_INLINE typename basic_array::iterator basic_array::begin() noexcept -{ - return _array_data.begin(); -} - -template -MEOJSON_INLINE typename basic_array::iterator basic_array::end() noexcept -{ - return _array_data.end(); -} - -template -MEOJSON_INLINE typename basic_array::const_iterator basic_array::begin() const noexcept -{ - return _array_data.begin(); -} - -template -MEOJSON_INLINE typename basic_array::const_iterator basic_array::end() const noexcept -{ - return _array_data.end(); -} - -template -MEOJSON_INLINE typename basic_array::const_iterator basic_array::cbegin() const noexcept -{ - return _array_data.cbegin(); -} - -template -MEOJSON_INLINE typename basic_array::const_iterator basic_array::cend() const noexcept -{ - return _array_data.cend(); -} - -template -MEOJSON_INLINE typename basic_array::reverse_iterator basic_array::rbegin() noexcept -{ - return _array_data.rbegin(); -} - -template -MEOJSON_INLINE typename basic_array::reverse_iterator basic_array::rend() noexcept -{ - return _array_data.rend(); -} - -template -MEOJSON_INLINE typename basic_array::const_reverse_iterator basic_array::rbegin() const noexcept -{ - return _array_data.rbegin(); -} - -template -MEOJSON_INLINE typename basic_array::const_reverse_iterator basic_array::rend() const noexcept -{ - return _array_data.rend(); -} - -template -MEOJSON_INLINE typename basic_array::const_reverse_iterator basic_array::crbegin() const noexcept -{ - return _array_data.crbegin(); -} - -template -MEOJSON_INLINE typename basic_array::const_reverse_iterator basic_array::crend() const noexcept -{ - return _array_data.crend(); -} - -template -MEOJSON_INLINE basic_value& basic_array::operator[](size_t pos) -{ - return _array_data[pos]; -} - -template -MEOJSON_INLINE const basic_value& basic_array::operator[](size_t pos) const -{ - return _array_data[pos]; -} - -template -MEOJSON_INLINE basic_array basic_array::operator+(const basic_array& rhs) const& -{ - basic_array temp = *this; - temp._array_data.insert(_array_data.end(), rhs.begin(), rhs.end()); - return temp; -} - -template -MEOJSON_INLINE basic_array basic_array::operator+(basic_array&& rhs) const& -{ - basic_array temp = *this; - temp._array_data.insert(_array_data.end(), std::make_move_iterator(rhs.begin()), - std::make_move_iterator(rhs.end())); - return temp; -} - -template -MEOJSON_INLINE basic_array basic_array::operator+(const basic_array& rhs) && -{ - _array_data.insert(_array_data.end(), rhs.begin(), rhs.end()); - return std::move(*this); -} - -template -MEOJSON_INLINE basic_array basic_array::operator+(basic_array&& rhs) && -{ - _array_data.insert(_array_data.end(), std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end())); - return std::move(*this); -} - -template -MEOJSON_INLINE basic_array& basic_array::operator+=(const basic_array& rhs) -{ - _array_data.insert(_array_data.end(), rhs.begin(), rhs.end()); - return *this; -} - -template -MEOJSON_INLINE basic_array& basic_array::operator+=(basic_array&& rhs) -{ - _array_data.insert(_array_data.end(), std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end())); - return *this; -} - -template -MEOJSON_INLINE bool basic_array::operator==(const basic_array& rhs) const -{ - return _array_data == rhs._array_data; -} - -// ******************************* -// * basic_object impl * -// ******************************* - -template -MEOJSON_INLINE basic_object::basic_object(const raw_object& raw_obj) : _object_data(raw_obj) -{ - ; -} - -template -MEOJSON_INLINE basic_object::basic_object(raw_object&& raw_obj) : _object_data(std::move(raw_obj)) -{ - ; -} - -template -MEOJSON_INLINE basic_object::basic_object(std::initializer_list init_list) -{ - for (const auto& [key, val] : init_list) { - emplace(key, val); - } -} - -template -MEOJSON_INLINE basic_object::basic_object(const basic_value& val) - : basic_object(val.as_object()) -{ - ; -} - -template -MEOJSON_INLINE basic_object::basic_object(basic_value&& val) - : basic_object(std::move(val.as_object())) -{ - ; -} - -template -MEOJSON_INLINE bool basic_object::contains(const string_t& key) const -{ - return _object_data.find(key) != _object_data.cend(); -} - -template -MEOJSON_INLINE const basic_value& basic_object::at(const string_t& key) const -{ - return _object_data.at(key); -} - -template -MEOJSON_INLINE void basic_object::clear() noexcept -{ - _object_data.clear(); -} - -template -MEOJSON_INLINE bool basic_object::erase(const string_t& key) -{ - return _object_data.erase(key) > 0 ? true : false; -} - -template -template -MEOJSON_INLINE decltype(auto) basic_object::emplace(args_t&&... args) -{ - static_assert(std::is_constructible_v, - "Parameter can't be used to construct a raw_object::value_type"); - return _object_data.emplace(std::forward(args)...); -} - -template -template -MEOJSON_INLINE decltype(auto) basic_object::insert(args_t&&... args) -{ - return emplace(std::forward(args)...); -} - -template -MEOJSON_INLINE string_t basic_object::to_string() const -{ - string_t str { '{' }; - for (auto iter = _object_data.cbegin(); iter != _object_data.cend();) { - const auto& [key, val] = *iter; - str += char_t('"') + unescape_string(key) + string_t { '\"', ':' } + val.to_string(); - if (++iter != _object_data.cend()) { - str += ','; - } - } - str += char_t('}'); - return str; -} - -template -MEOJSON_INLINE string_t basic_object::format(size_t indent, size_t indent_times) const -{ - const string_t tail_indent(indent * indent_times, ' '); - const string_t body_indent(indent * (indent_times + 1), ' '); - - string_t str { '{', '\n' }; - for (auto iter = _object_data.cbegin(); iter != _object_data.cend();) { - const auto& [key, val] = *iter; - str += body_indent + char_t('"') + unescape_string(key) + string_t { '\"', ':', ' ' } + - val.format(indent, indent_times + 1); - if (++iter != _object_data.cend()) { - str += ','; - } - str += '\n'; - } - str += tail_indent + char_t('}'); - return str; -} - -template -template -MEOJSON_INLINE auto basic_object::get_helper(const value_t& default_value, const string_t& key, - rest_keys_t&&... rest) const -{ - constexpr bool is_json = std::is_same_v, value_t> || - std::is_same_v, value_t> || - std::is_same_v, value_t>; - constexpr bool is_string = std::is_constructible_v && !is_json; - - if (!contains(key)) { - if constexpr (is_string) { - return string_t(default_value); - } - else { - return value_t(default_value); - } - } - - return at(key).get_helper(default_value, std::forward(rest)...); -} - -template -template -MEOJSON_INLINE auto basic_object::get_helper(const value_t& default_value, const string_t& key) const -{ - constexpr bool is_json = std::is_same_v, value_t> || - std::is_same_v, value_t> || - std::is_same_v, value_t>; - constexpr bool is_string = std::is_constructible_v && !is_json; - - if (!contains(key)) { - if constexpr (is_string) { - return string_t(default_value); - } - else { - return value_t(default_value); - } - } - - auto val = _object_data.at(key); - if (val.template is()) { - if constexpr (is_string) { - return val.template as(); - } - else { - return val.template as(); - } - } - else { - if constexpr (is_string) { - return string_t(default_value); - } - else { - return value_t(default_value); - } - } -} - -template -template -MEOJSON_INLINE std::optional basic_object::find(const string_t& key) const -{ - static_assert(std::is_constructible_v>, - "value_t can NOT be constructed by basic_value"); - auto iter = _object_data.find(key); - if (iter == _object_data.end()) { - return std::nullopt; - } - const auto& val = iter->second; - return val.template is() ? std::optional(val.template as()) : std::nullopt; -} - -template -MEOJSON_INLINE typename basic_object::iterator basic_object::begin() noexcept -{ - return _object_data.begin(); -} - -template -MEOJSON_INLINE typename basic_object::iterator basic_object::end() noexcept -{ - return _object_data.end(); -} - -template -MEOJSON_INLINE typename basic_object::const_iterator basic_object::begin() const noexcept -{ - return _object_data.begin(); -} - -template -MEOJSON_INLINE typename basic_object::const_iterator basic_object::end() const noexcept -{ - return _object_data.end(); -} - -template -MEOJSON_INLINE typename basic_object::const_iterator basic_object::cbegin() const noexcept -{ - return _object_data.cbegin(); -} - -template -MEOJSON_INLINE typename basic_object::const_iterator basic_object::cend() const noexcept -{ - return _object_data.cend(); -} - -template -MEOJSON_INLINE basic_value& basic_object::operator[](const string_t& key) -{ - return _object_data[key]; -} - -template -MEOJSON_INLINE basic_value& basic_object::operator[](string_t&& key) -{ - return _object_data[std::move(key)]; -} - -template -MEOJSON_INLINE basic_object basic_object::operator|(const basic_object& rhs) const& -{ - basic_object temp = *this; - temp._object_data.insert(rhs.begin(), rhs.end()); - return temp; -} - -template -MEOJSON_INLINE basic_object basic_object::operator|(basic_object&& rhs) const& -{ - basic_object temp = *this; - // temp._object_data.merge(std::move(rhs._object_data)); - temp._object_data.insert(std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end())); - return temp; -} - -template -MEOJSON_INLINE basic_object basic_object::operator|(const basic_object& rhs) && -{ - _object_data.insert(rhs.begin(), rhs.end()); - return std::move(*this); -} - -template -MEOJSON_INLINE basic_object basic_object::operator|(basic_object&& rhs) && -{ - //_object_data.merge(std::move(rhs._object_data)); - _object_data.insert(std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end())); - return std::move(*this); -} - -template -MEOJSON_INLINE basic_object& basic_object::operator|=(const basic_object& rhs) -{ - _object_data.insert(rhs.begin(), rhs.end()); - return *this; -} - -template -MEOJSON_INLINE basic_object& basic_object::operator|=(basic_object&& rhs) -{ - _object_data.insert(std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end())); - return *this; -} - -template -MEOJSON_INLINE bool basic_object::operator==(const basic_object& rhs) const -{ - return _object_data == rhs._object_data; -} - -// ************************* -// * parser impl * -// ************************* - -template -MEOJSON_INLINE std::optional> parser::parse( - const parsing_t& content) -{ - return parser(content.cbegin(), content.cend()).parse(); -} - -template -MEOJSON_INLINE std::optional> parser::parse() -{ - if (!skip_whitespace()) { - return std::nullopt; - } - - basic_value result_value; - switch (*_cur) { - case '[': - result_value = parse_array(); - break; - case '{': - result_value = parse_object(); - break; - default: // A JSON payload should be an basic_object or basic_array - return std::nullopt; - } - - if (!result_value.valid()) { - return std::nullopt; - } - - // After the parsing is complete, there should be no more content other than - // spaces behind - if (skip_whitespace()) { - return std::nullopt; - } - - return result_value; -} - -template -MEOJSON_INLINE basic_value parser::parse_value() -{ - switch (*_cur) { - case 'n': - return parse_null(); - case 't': - case 'f': - return parse_boolean(); - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return parse_number(); - case '"': - return parse_string(); - case '[': - return parse_array(); - case '{': - return parse_object(); - default: - return invalid_value(); - } -} - -template -MEOJSON_INLINE basic_value parser::parse_null() -{ - for (const auto& ch : null_string()) { - if (*_cur == ch) { - ++_cur; - } - else { - return invalid_value(); - } - } - - return basic_value(); -} - -template -MEOJSON_INLINE basic_value parser::parse_boolean() -{ - switch (*_cur) { - case 't': - for (const auto& ch : true_string()) { - if (*_cur == ch) { - ++_cur; - } - else { - return invalid_value(); - } - } - return true; - case 'f': - for (const auto& ch : false_string()) { - if (*_cur == ch) { - ++_cur; - } - else { - return invalid_value(); - } - } - return false; - default: - return invalid_value(); - } -} - -template -MEOJSON_INLINE basic_value parser::parse_number() -{ - const auto first = _cur; - if (*_cur == '-') { - ++_cur; - } - - // numbers cannot have leading zeroes - if (_cur != _end && *_cur == '0' && _cur + 1 != _end && std::isdigit(*(_cur + 1))) { - return invalid_value(); - } - - if (!skip_digit()) { - return invalid_value(); - } - - if (*_cur == '.') { - ++_cur; - if (!skip_digit()) { - return invalid_value(); - } - } - - if (*_cur == 'e' || *_cur == 'E') { - if (++_cur == _end) { - return invalid_value(); - } - if (*_cur == '+' || *_cur == '-') { - ++_cur; - } - if (!skip_digit()) { - return invalid_value(); - } - } - - return basic_value(basic_value::value_type::number, string_t(first, _cur)); -} - -template -MEOJSON_INLINE basic_value parser::parse_string() -{ - auto string_opt = parse_stdstring(); - if (!string_opt) { - return invalid_value(); - } - return basic_value(basic_value::value_type::string, std::move(string_opt).value()); -} - -template -MEOJSON_INLINE basic_value parser::parse_array() -{ - if (*_cur == '[') { - ++_cur; - } - else { - return invalid_value(); - } - - if (!skip_whitespace()) { - return invalid_value(); - } - else if (*_cur == ']') { - ++_cur; - // empty basic_array - return basic_array(); - } - - typename basic_array::raw_array result; - while (true) { - if (!skip_whitespace()) { - return invalid_value(); - } - - basic_value val = parse_value(); - - if (!val.valid() || !skip_whitespace()) { - return invalid_value(); - } - - result.emplace_back(std::move(val)); - - if (*_cur == ',') { - ++_cur; - } - else { - break; - } - } - - if (skip_whitespace() && *_cur == ']') { - ++_cur; - } - else { - return invalid_value(); - } - - return basic_array(std::move(result)); -} - -template -MEOJSON_INLINE basic_value parser::parse_object() -{ - if (*_cur == '{') { - ++_cur; - } - else { - return invalid_value(); - } - - if (!skip_whitespace()) { - return invalid_value(); - } - else if (*_cur == '}') { - ++_cur; - // empty basic_object - return basic_object(); - } - - typename basic_object::raw_object result; - while (true) { - if (!skip_whitespace()) { - return invalid_value(); - } - - auto key_opt = parse_stdstring(); - - if (key_opt && skip_whitespace() && *_cur == ':') { - ++_cur; - } - else { - return invalid_value(); - } - - if (!skip_whitespace()) { - return invalid_value(); - } - - basic_value val = parse_value(); - - if (!val.valid() || !skip_whitespace()) { - return invalid_value(); - } - - result.emplace(std::move(*key_opt), std::move(val)); - - if (*_cur == ',') { - ++_cur; - } - else { - break; - } - } - - if (skip_whitespace() && *_cur == '}') { - ++_cur; - } - else { - return invalid_value(); - } - - return basic_object(std::move(result)); -} - -template -MEOJSON_INLINE std::optional parser::parse_stdstring() -{ - if (*_cur == '"') { - ++_cur; - } - else { - return std::nullopt; - } - - string_t result; - auto no_escape_beg = _cur; - - while (_cur != _end) { - if constexpr (sizeof(*_cur) == 1) { - if constexpr (accel_traits::available) { - skip_string_literal(); - } - } - switch (*_cur) { - case '\t': - case '\r': - case '\n': - return std::nullopt; - case '\\': { - result += string_t(no_escape_beg, _cur++); - if (_cur == _end) { - return std::nullopt; - } - switch (*_cur) { - case '"': - result.push_back('"'); - break; - case '\\': - result.push_back('\\'); - break; - case '/': - result.push_back('/'); - break; - case 'b': - result.push_back('\b'); - break; - case 'f': - result.push_back('\f'); - break; - case 'n': - result.push_back('\n'); - break; - case 'r': - result.push_back('\r'); - break; - case 't': - result.push_back('\t'); - break; - // case 'u': - // result.push_back('\u'); - // break; - default: - // Illegal backslash escape - return std::nullopt; - } - no_escape_beg = ++_cur; - break; - } - case '"': { - result += string_t(no_escape_beg, _cur++); - return result; - } - default: - ++_cur; - break; - } - } - return std::nullopt; -} - -template -MEOJSON_INLINE void parser::skip_string_literal() -{ - if constexpr (sizeof(*_cur) != 1) { - return; - } - while (_end - _cur >= accel_traits::step) { - auto pack = accel_traits::load_unaligned(&(*_cur)); - auto result = accel_traits::less(pack, 32); - result = accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast('"'))); - result = accel_traits::bitwise_or(result, accel_traits::equal(pack, static_cast('\\'))); - if (accel_traits::is_all_zero(result)) { - _cur += accel_traits::step; - } - else { - auto index = accel_traits::first_nonzero_byte(result); - _cur += index; - break; - } - } -} - -template -MEOJSON_INLINE bool parser::skip_whitespace() noexcept -{ - while (_cur != _end) { - switch (*_cur) { - case ' ': - case '\t': - case '\r': - case '\n': - ++_cur; - break; - case '\0': - return false; - default: - return true; - } - } - return false; -} - -template -MEOJSON_INLINE bool parser::skip_digit() -{ - // At least one digit - if (_cur != _end && std::isdigit(*_cur)) { - ++_cur; - } - else { - return false; - } - - while (_cur != _end && std::isdigit(*_cur)) { - ++_cur; - } - - if (_cur != _end) { - return true; - } - else { - return false; - } -} - -// ************************* -// * utils impl * -// ************************* - -template -MEOJSON_INLINE auto parse(const parsing_t& content) -{ - using string_t = std::basic_string; - return parser::parse(content); -} - -template -MEOJSON_INLINE auto parse(istream_t& ifs, bool check_bom) -{ - using string_t = std::basic_string; - - ifs.seekg(0, std::ios::end); - auto file_size = ifs.tellg(); - - ifs.seekg(0, std::ios::beg); - string_t str(file_size, '\0'); - - ifs.read(str.data(), file_size); - - if (check_bom) { - using uchar = unsigned char; - static constexpr uchar Bom_0 = 0xEF; - static constexpr uchar Bom_1 = 0xBB; - static constexpr uchar Bom_2 = 0xBF; - - if (str.size() >= 3 && static_cast(str.at(0)) == Bom_0 && static_cast(str.at(1)) == Bom_1 && - static_cast(str.at(2)) == Bom_2) { - str.assign(str.begin() + 3, str.end()); - } - } - return parse(str); -} - -template -MEOJSON_INLINE auto open(const path_t& filepath, bool check_bom) -{ - using char_t = typename ifstream_t::char_type; - using string_t = std::basic_string; - using json_t = json::basic_value; - using return_t = std::optional; - - ifstream_t ifs(filepath, std::ios::in); - if (!ifs.is_open()) { - return return_t(std::nullopt); - } - auto opt = parse(ifs, check_bom); - ifs.close(); - return opt; -} - -template >, - typename enable_t = typename std::enable_if_t || - std::is_base_of_v>> -ostream_t& operator<<(ostream_t& out, const basic_value& val) -{ - out << val.format(); - return out; -} -template >, - typename enable_t = - std::enable_if_t || std::is_base_of_v>> -ostream_t& operator<<(ostream_t& out, const basic_array& arr) -{ - out << arr.format(); - return out; -} -template >, - typename enable_t = - std::enable_if_t || std::is_base_of_v>> -ostream_t& operator<<(ostream_t& out, const basic_object& obj) -{ - out << obj.format(); - return out; -} - -namespace literals -{ - MEOJSON_INLINE value operator""_json(const char* str, size_t len) - { - return operator""_jvalue(str, len); - } - MEOJSON_INLINE wvalue operator""_json(const wchar_t* str, size_t len) - { - return operator""_jvalue(str, len); - } - MEOJSON_INLINE u16value operator""_json(const char16_t* str, size_t len) - { - return operator""_jvalue(str, len); - } - MEOJSON_INLINE u32value operator""_json(const char32_t* str, size_t len) - { - return operator""_jvalue(str, len); - } - - MEOJSON_INLINE value operator""_jvalue(const char* str, size_t len) - { - return parse(std::string_view(str, len)).value_or(value()); - } - MEOJSON_INLINE wvalue operator""_jvalue(const wchar_t* str, size_t len) - { - return parse(std::wstring_view(str, len)).value_or(wvalue()); - } - MEOJSON_INLINE u16value operator""_jvalue(const char16_t* str, size_t len) - { - return parse(std::u16string_view(str, len)).value_or(u16value()); - } - MEOJSON_INLINE u32value operator""_jvalue(const char32_t* str, size_t len) - { - return parse(std::u32string_view(str, len)).value_or(u32value()); - } - - MEOJSON_INLINE array operator""_jarray(const char* str, size_t len) - { - auto val = parse(std::string_view(str, len)).value_or(value()); - return val.is_array() ? val.as_array() : array(); - } - MEOJSON_INLINE warray operator""_jarray(const wchar_t* str, size_t len) - { - auto val = parse(std::wstring_view(str, len)).value_or(wvalue()); - return val.is_array() ? val.as_array() : warray(); - } - MEOJSON_INLINE u16array operator""_jarray(const char16_t* str, size_t len) - { - auto val = parse(std::u16string_view(str, len)).value_or(u16value()); - return val.is_array() ? val.as_array() : u16array(); - } - MEOJSON_INLINE u32array operator""_jarray(const char32_t* str, size_t len) - { - auto val = parse(std::u32string_view(str, len)).value_or(u32value()); - return val.is_array() ? val.as_array() : u32array(); - } - - MEOJSON_INLINE object operator""_jobject(const char* str, size_t len) - { - auto val = parse(std::string_view(str, len)).value_or(value()); - return val.is_object() ? val.as_object() : object(); - } - MEOJSON_INLINE wobject operator""_jobject(const wchar_t* str, size_t len) - { - auto val = parse(std::wstring_view(str, len)).value_or(wvalue()); - return val.is_object() ? val.as_object() : wobject(); - } - MEOJSON_INLINE u16object operator""_jobject(const char16_t* str, size_t len) - { - auto val = parse(std::u16string_view(str, len)).value_or(u16value()); - return val.is_object() ? val.as_object() : u16object(); - } - MEOJSON_INLINE u32object operator""_jobject(const char32_t* str, size_t len) - { - auto val = parse(std::u32string_view(str, len)).value_or(u32value()); - return val.is_object() ? val.as_object() : u32object(); - } -} // namespace literals - -template -MEOJSON_INLINE const basic_value invalid_value() -{ - return basic_value(basic_value::value_type::invalid, typename basic_value::var_t()); -} - -namespace _serialization_helper -{ - template - class has_output_operator - { - template - static auto test(int) -> decltype(std::declval() << std::declval(), std::true_type()); - - template - static std::false_type test(...); - - public: - static constexpr bool value = decltype(test(0))::value; - }; - - template - using void_t = void; - - template - constexpr bool is_container = false; - template - constexpr bool is_container< - T, void_t().begin()), decltype(std::declval().end())>> = - true; - - // something like a map - template - constexpr bool is_associative_container = false; - template - constexpr bool is_associative_container> = is_container; - - // something like a vector - template - constexpr bool is_sequence_container = false; - template - constexpr bool is_sequence_container = is_container && !is_associative_container; - - template - MEOJSON_INLINE string_t to_stream_string(input_t&& arg) - { - if constexpr (has_output_operator::value) { - using char_t = typename string_t::value_type; - using stringstream_t = std::basic_stringstream, std::allocator>; - - stringstream_t ss; - ss << std::forward(arg); - return std::move(ss).str(); - } - else { - static_assert(!sizeof(input_t), "Unable to convert type to string, there is no operator <<."); - } - } - - template - MEOJSON_INLINE string_t to_string(input_t&& arg) - { - if constexpr (std::is_constructible_v) { - return arg; - } - else if constexpr (loose) { - return to_stream_string(std::forward(arg)); - } - else { - static_assert(!sizeof(input_t), "Unable to convert type to string."); - } - } -} - -template -MEOJSON_INLINE basic_value serialize(any_t&& arg) -{ - using namespace _serialization_helper; - - if constexpr (std::is_constructible_v, any_t>) { - return arg; - } - else if constexpr (std::is_constructible_v, any_t>) { - return basic_array(std::forward(arg)); - } - else if constexpr (std::is_constructible_v, any_t>) { - return basic_object(std::forward(arg)); - } - else if constexpr (is_sequence_container>) { - basic_value result; - for (auto&& val : arg) { - using value_t = decltype(val); - - result.emplace(serialize(std::forward(val))); - } - return result; - } - else if constexpr (is_associative_container>) { - basic_value result; - for (auto&& [key, val] : arg) { - using key_t = decltype(key); - using value_t = decltype(val); - - result.emplace(to_string(std::forward(key)), - serialize(std::forward(val))); - } - return result; - } - else { - return to_string(std::forward(arg)); - } -} - -template -MEOJSON_INLINE static constexpr string_t unescape_string(const string_t& str) -{ - using char_t = typename string_t::value_type; - - string_t result; - auto cur = str.cbegin(); - auto end = str.cend(); - auto no_escape_beg = cur; - char_t escape = 0; - - for (; cur != end; ++cur) { - switch (*cur) { - case '"': - escape = '"'; - break; - case '\\': - escape = '\\'; - break; - case '\b': - escape = 'b'; - break; - case '\f': - escape = 'f'; - break; - case '\n': - escape = 'n'; - break; - case '\r': - escape = 'r'; - break; - case '\t': - escape = 't'; - break; - default: - break; - } - if (escape) { - result += string_t(no_escape_beg, cur) + char_t('\\') + escape; - no_escape_beg = cur + 1; - escape = 0; - } - } - result += string_t(no_escape_beg, cur); - - return result; -} -} // namespace json diff --git a/source/cli/meojson/packed_bytes.hpp b/source/cli/meojson/packed_bytes.hpp deleted file mode 100644 index c471777..0000000 --- a/source/cli/meojson/packed_bytes.hpp +++ /dev/null @@ -1,126 +0,0 @@ -#pragma once -#include -#include -#include -#include "bitops.hpp" - -#if defined(__GNUC__) || defined(__clang__) -#define __packed_bytes_strong_inline __attribute__((always_inline)) -#elif defined(_MSC_VER) -#define __packed_bytes_strong_inline __forceinline -#else -#define __packed_bytes_strong_inline inline -#endif - -struct packed_bytes_trait_none { - static constexpr bool available = false; -}; - -template -struct packed_bytes { - using traits = packed_bytes_trait_none; -}; - -#if defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP) -#include "packed_bytes_x86.hpp" -#elif defined(__ARM_NEON) || defined(_M_ARM) || defined(_M_ARM64) -#include "packed_bytes_arm.hpp" -#endif - -struct packed_bytes_trait_uint64 { - static constexpr bool available = sizeof(void*) >= 8; - static constexpr auto step = 8; - using value_type = std::enable_if_t= 8, uint64_t>; - - __packed_bytes_strong_inline static value_type load_unaligned(const void *ptr) { - value_type result; - memcpy((void*)&result, ptr, 8); - return result; - } - - __packed_bytes_strong_inline static value_type less(value_type x, uint8_t n) { - return (((x) - UINT64_C(0x0101010101010101) * (n)) & ~(x) & UINT64_C(0x8080808080808080)); - } - - __packed_bytes_strong_inline static value_type is_zero_memberwise(value_type v) { - return (((v) - UINT64_C(0x0101010101010101)) & ~(v) & UINT64_C(0x8080808080808080)); - } - - __packed_bytes_strong_inline static bool is_all_zero(value_type v) - { - return v == UINT64_C(0); - } - - __packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n) { - return is_zero_memberwise((x) ^ (UINT64_C(0x0101010101010101) * (n))); - } - - __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { - return a | b; - } - - __packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x) { - if (json::__bitops::is_little_endian()) - return json::__bitops::countr_zero(x) / 8; - else - return json::__bitops::countl_zero(x) / 8; - } -}; - -struct packed_bytes_trait_uint32 { - static constexpr bool available = true; - static constexpr auto step = 4; - using value_type = uint32_t; - - __packed_bytes_strong_inline static value_type load_unaligned(const void *ptr) { - value_type result; - memcpy((void*)&result, ptr, 4); - return result; - } - - __packed_bytes_strong_inline static value_type less(value_type x, uint8_t n) { - return (((x) - ~UINT32_C(0) / 255 * (n)) & ~(x) & ~UINT32_C(0) / 255 * 128); - } - - __packed_bytes_strong_inline static value_type is_zero_memberwise(value_type v) { - return (((v) - UINT32_C(0x01010101)) & ~(v) & UINT32_C(0x80808080));; - } - - __packed_bytes_strong_inline static bool is_all_zero(value_type v) { - return v == UINT32_C(0); - } - - __packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n) { - return is_zero_memberwise((x) ^ (~UINT32_C(0) / 255 * (n))); - } - - __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { - return a | b; - } - - __packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x) { - if (json::__bitops::is_little_endian()) - return json::__bitops::countr_zero(x) / 8; - else - return json::__bitops::countl_zero(x) / 8; - } -}; -template <> -struct packed_bytes<8> { - using traits = std::enable_if_t; -}; - -template <> -struct packed_bytes<4> { - using traits = packed_bytes_trait_uint32; -}; - -template -using packed_bytes_trait = typename packed_bytes::traits; - -using packed_bytes_trait_max = std::conditional_t::available, packed_bytes_trait<32>, - std::conditional_t::available, packed_bytes_trait<16>, - std::conditional_t::available, packed_bytes_trait<8>, - packed_bytes_trait<4> - >>>; - diff --git a/source/cli/meojson/packed_bytes_arm.hpp b/source/cli/meojson/packed_bytes_arm.hpp deleted file mode 100644 index 86fc07f..0000000 --- a/source/cli/meojson/packed_bytes_arm.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -// current NEON implementation doesn't outperform 64-bit scalar implementation -#ifdef MEOJSON_ENABLE_NEON -#include "packed_bytes.hpp" -#include - -#if defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) -#define __packed_bytes_trait_arm64 -#endif - -struct packed_bytes_trait_neon { - static constexpr bool available = true; - static constexpr auto step = 16; - using value_type = uint8x16_t; - - __packed_bytes_strong_inline static value_type load_unaligned(const void *ptr) { - return vld1q_u8((uint8_t*)ptr); - } - - __packed_bytes_strong_inline static value_type less(value_type x, uint8_t n) { - auto bcast = vdupq_n_u8(n); - auto is_less = vcltq_u8(x, bcast); - return is_less; - } - - __packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n) { - return vceqq_u8(x, vdupq_n_u8(n)); - } - - __packed_bytes_strong_inline static value_type equal(value_type x, value_type y) { - return vceqq_u8(x, y); - } - - __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { - return vorrq_u8(a, b); - } - - __packed_bytes_strong_inline static bool is_all_zero(value_type x) { -#ifdef __packed_bytes_trait_arm64 - return vmaxvq_u8(x) == 0; -#else - auto fold64 = vorr_u64(vget_high_u64(vreinterpretq_u8_u64(x), 0), vget_low_u64(vreinterpretq_u8_u64(x), 1)); - auto fold32 = vget_lane_u32(vreinterpret_u64_u32(fold64), 0) | vget_lane_u32(vreinterpret_u64_u32(fold64), 1); - return fold32 == 0; -#endif - } - - __packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x) { - // https://community.arm.com/arm-community-blogs/b/infrastructure-solutions-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon - auto cmp = equal(x, 0); - auto res = vshrn_n_u16(cmp, 4); - auto mask64 = vget_lane_u64(vreinterpret_u64_u8(res), 0); - return json::__bitops::countr_one(mask64) >> 2; - } -}; - -template <> -struct packed_bytes<16> { - using traits = packed_bytes_trait_neon; -}; - -#endif diff --git a/source/cli/meojson/packed_bytes_x86.hpp b/source/cli/meojson/packed_bytes_x86.hpp deleted file mode 100644 index afa6951..0000000 --- a/source/cli/meojson/packed_bytes_x86.hpp +++ /dev/null @@ -1,123 +0,0 @@ -#pragma once -#include "packed_bytes.hpp" - -#include -#if defined(__SSE4_1__) || defined(__AVX2__) || defined(_MSC_VER) -// MSVC enables all SSE4.1 intrinsics by default -#include -#endif - -struct packed_bytes_trait_sse { - static constexpr bool available = true; - static constexpr auto step = 16; - using value_type = __m128i; - - __packed_bytes_strong_inline static value_type load_unaligned(const void *ptr) { - return _mm_loadu_si128(reinterpret_cast(ptr)); - } - - __packed_bytes_strong_inline static value_type less(value_type x, uint8_t n) { - auto bcast = _mm_set1_epi8(static_cast(n)); - auto all1 = _mm_set1_epi8(-1); - auto max_with_n = _mm_max_epu8(x, bcast); - auto is_greater_or_equal = _mm_cmpeq_epi8(max_with_n, x); - auto is_less = _mm_andnot_si128(is_greater_or_equal, all1); - return is_less; - } - - __packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n) { - return _mm_cmpeq_epi8(x, _mm_set1_epi8(static_cast(n))); - } - - __packed_bytes_strong_inline static value_type equal(value_type x, value_type y) { - return _mm_cmpeq_epi8(x, y); - } - - __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) { - return _mm_or_si128(a, b); - } - - __packed_bytes_strong_inline static bool is_all_zero(value_type x) { -#if defined(__SSE4_1__) || defined(__AVX2__) || defined(_MSC_VER) - // SSE4.1 path - return !!_mm_testz_si128(x, x); -#else - // SSE2 path - auto cmp = _mm_cmpeq_epi8(x, _mm_set1_epi8(0)); - auto mask = (uint16_t)_mm_movemask_epi8(cmp); - return mask == UINT16_C(0xFFFF); -#endif - } - - __packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x) { - auto cmp = _mm_cmpeq_epi8(x, _mm_set1_epi8(0)); - auto mask = (uint16_t)_mm_movemask_epi8(cmp); - return json::__bitops::countr_one((uint32_t)mask); - } -}; - -template <> -struct packed_bytes<16> { - using traits = packed_bytes_trait_sse; -}; - - -#ifdef __AVX2__ -#include - -struct packed_bytes_trait_avx2 -{ - static constexpr bool available = true; - static constexpr auto step = 32; - using value_type = __m256i; - - __packed_bytes_strong_inline static value_type load_unaligned(const void* ptr) - { - return _mm256_loadu_si256(reinterpret_cast(ptr)); - } - - __packed_bytes_strong_inline static value_type less(value_type x, uint8_t n) - { - auto bcast = _mm256_set1_epi8(static_cast(n)); - auto all1 = _mm256_set1_epi8(-1); - auto max_with_n = _mm256_max_epu8(x, bcast); - auto is_greater_or_equal = _mm256_cmpeq_epi8(max_with_n, x); - auto is_less = _mm256_andnot_si256(is_greater_or_equal, all1); - return is_less; - } - - __packed_bytes_strong_inline static value_type equal(value_type x, uint8_t n) - { - return _mm256_cmpeq_epi8(x, _mm256_set1_epi8(static_cast(n))); - } - - __packed_bytes_strong_inline static value_type equal(value_type x, value_type y) - { - return _mm256_cmpeq_epi8(x, y); - } - - __packed_bytes_strong_inline static value_type bitwise_or(value_type a, value_type b) - { - return _mm256_or_si256(a, b); - } - - __packed_bytes_strong_inline static bool is_all_zero(value_type x) - { - return (bool)_mm256_testz_si256(x, x); - } - - __packed_bytes_strong_inline static size_t first_nonzero_byte(value_type x) - { - auto cmp = _mm256_cmpeq_epi8(x, _mm256_set1_epi8(0)); - auto mask = (uint32_t)_mm256_movemask_epi8(cmp); - // AVX512 alternative: _mm_cmpeq_epi8_mask - return json::__bitops::countr_one(mask); - } -}; - -template <> -struct packed_bytes<32> { - using traits = packed_bytes_trait_avx2; -}; - -#endif diff --git a/tools/ImageCropper/dst/.gitkeep b/tools/ImageCropper/dst/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tools/ImageCropper/main.py b/tools/ImageCropper/main.py deleted file mode 100644 index 93d118c..0000000 --- a/tools/ImageCropper/main.py +++ /dev/null @@ -1,122 +0,0 @@ -import cv2 -import os - - -print("Usage:\n" - "Put the 16:9 images under ./src, and run this script, it will be auto converted to 720p.\n" - "Drag mouse to select ROI, press 'S' to save, press 'Q' to quit.\n" - "The cropped images will be saved in ./dst\n") - - -# 初始化参考点列表和布尔值标志:是否正在执行裁剪 -refPt = [] -cropping = False - - -# 点击并裁剪ROI区域 -# -events 鼠标事件(如按下鼠标左键,释放鼠标左键,鼠标移动等) -# -x x坐标 -# -y y坐标 -# -flages params 其他参数 -def click_and_crop(event, x, y, flags, param): - # 获取全局变量的引用 - global refPt, cropping - - # 如果鼠标左被单击,记录(x,y)坐标并显示裁剪正在进行 - if event == cv2.EVENT_LBUTTONDOWN: - refPt = [(x, y)] - cropping = True - # 检测鼠标左键是否释放 - elif event == cv2.EVENT_LBUTTONUP: - # 记录结束(x,y)坐标,并显示裁剪结束 - refPt.append((x, y)) - cropping = False - - draw = image.copy() - cv2.rectangle(draw, refPt[0], refPt[1], (0, 255, 0), 2) - cv2.imshow("image", draw) - - -std_long_side: int = 1280 -std_short_side: int = 720 -std_ratio = std_long_side / std_short_side - -cv2.namedWindow("image", cv2.WINDOW_NORMAL) -cv2.setMouseCallback("image", click_and_crop) - -for filename in os.listdir("./src"): - if not filename.endswith(".png"): - continue - - print("src:", filename) - image = cv2.imread("./src/" + filename) - - - if image.shape[1] > image.shape[0]: # landscape - cur_ratio = image.shape[1] / image.shape[0] - if cur_ratio >= std_ratio: # 说明是宽屏或默认16:9,按照高度计算缩放 - dsize_width: int = (int)(cur_ratio * std_short_side) - dsize_height: int = std_short_side - else: # 否则可能是偏正方形的屏幕,按宽度计算 - dsize_width: int = std_long_side - dsize_height: int = (int)(std_long_side / cur_ratio) - else: # portrait - cur_ratio = image.shape[0] / image.shape[1] - if cur_ratio >= std_ratio: # 说明是宽屏或默认16:9,按照高度计算缩放 - dsize_width: int = std_short_side - dsize_height: int = (int)(std_short_side * cur_ratio) - else: # 否则可能是偏正方形的屏幕,按宽度计算 - dsize_width: int = (int)(std_long_side / cur_ratio) - dsize_height: int = std_long_side - - dsize = (dsize_width, dsize_height) - image = cv2.resize(image, dsize, interpolation=cv2.INTER_AREA) - - while True: - cv2.imshow("image", image) - key = cv2.waitKey(0) & 0xFF - if key == ord("s"): - break - elif key == ord("q"): - exit() - - # 如果参考点列表里有俩个点,则裁剪区域并展示 - if len(refPt) == 2: - if refPt[0][0] > refPt[1][0] or refPt[0][1] > refPt[1][1]: - refPt[0], refPt[1] = refPt[1], refPt[0] - left = refPt[0][0] - right = refPt[1][0] - top = refPt[0][1] - bottom = refPt[1][1] - - roi = image[top:bottom, left:right] - - horizontal_expansion = 100 - vertical_expansion = 100 - - filename_x: int = (int)(left - horizontal_expansion / 2) - if filename_x < 0: - filename_x = 0 - filename_y: int = (int)(top - vertical_expansion / 2) - if filename_y < 0: - filename_y = 0 - filename_w: int = (right - left) + horizontal_expansion - if filename_x + filename_w > dsize_width: - filename_w = dsize_width - filename_x - filename_h: int = (bottom - top) + vertical_expansion - if filename_y + filename_h > dsize_height: - filename_h = dsize_height - filename_y - - dst_filename: str = f'{filename}_{filename_x},{filename_y},{filename_w},{filename_h}.png' - print('dst:', dst_filename) - - print(f"original roi: {left}, {top}, {right - left}, {bottom - top}, \n" - f"amplified roi: {filename_x}, {filename_y}, {filename_w}, {filename_h}\n\n") - - cv2.imwrite('./dst/' + dst_filename, roi) - - refPt = [] - cropping = False - -# 关闭所有打开的窗口 -cv2.destroyAllWindows() diff --git a/tools/ImageCropper/requirements.txt b/tools/ImageCropper/requirements.txt deleted file mode 100644 index 07d7224..0000000 --- a/tools/ImageCropper/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -opencv-python~=4.5.3 diff --git a/tools/ImageCropper/src/.gitkeep b/tools/ImageCropper/src/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tools/ImageCropper/start.bat b/tools/ImageCropper/start.bat deleted file mode 100644 index 134732e..0000000 --- a/tools/ImageCropper/start.bat +++ /dev/null @@ -1,2 +0,0 @@ -python main.py -pause \ No newline at end of file