diff --git a/.github/workflows/Orbis474.yml b/.github/workflows/Orbis474.yml deleted file mode 100644 index 1a78b9d8..00000000 --- a/.github/workflows/Orbis474.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Orbis474 - -on: - push: - branches: [ master, develop ] - pull_request: - branches: [ master, develop ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - # Checkout the repository - - uses: actions/checkout@v2 - # Install required stuff needed to build Mira - - name: preinstall - run: sudo apt install build-essential git clang lldb clang-tidy clang-tools cppcheck - # Handle loader crap - - name: create loader directories - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_474 make create - - name: clean loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_474 make clean - - name: create mira directories - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_474 make create - - name: clean mira - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_474 make clean - # 4.74 Support - - name: make 4.74 loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_474 MIRA_CHECKS=TRUE make - - name: make 4.74 elf - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_474 ADD_GIT_HASH=TRUE MIRA_CHECKS=TRUE make - - name: Upload 4.74 loader - uses: actions/upload-artifact@v2 - with: - name: MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_474.bin - path: loader/build/MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_474.bin - - name: Upload 4.74 elf - uses: actions/upload-artifact@v2 - with: - name: Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_474.elf - path: kernel/build/Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_474.elf diff --git a/.github/workflows/Orbis501.yml b/.github/workflows/Orbis501.yml deleted file mode 100644 index 16cb6423..00000000 --- a/.github/workflows/Orbis501.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Orbis501 - -on: - push: - branches: [ master, develop ] - pull_request: - branches: [ master, develop ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - # Checkout the repository - - uses: actions/checkout@v2 - # Install required stuff needed to build Mira - - name: preinstall - run: sudo apt install build-essential git clang lldb clang-tidy clang-tools cppcheck - # Handle loader crap - - name: create loader directories - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_501 make create - - name: clean loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_501 make clean - - name: create mira directories - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_501 make create - - name: clean mira - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_501 make clean - # 5.01 Support - - name: make 5.01 loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_501 MIRA_CHECKS=TRUE make - - name: make 5.01 elf - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_501 ADD_GIT_HASH=TRUE MIRA_CHECKS=TRUE make - - name: Upload 5.01 loader - uses: actions/upload-artifact@v2 - with: - name: MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_501.bin - path: loader/build/MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_501.bin - - name: Upload 5.01 elf - uses: actions/upload-artifact@v2 - with: - name: Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_501.elf - path: kernel/build/Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_501.elf diff --git a/.github/workflows/Orbis503.yml b/.github/workflows/Orbis503.yml deleted file mode 100644 index 745fab14..00000000 --- a/.github/workflows/Orbis503.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Orbis503 - -on: - push: - branches: [ master, develop ] - pull_request: - branches: [ master, develop ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - # Checkout the repository - - uses: actions/checkout@v2 - # Install required stuff needed to build Mira - - name: preinstall - run: sudo apt install build-essential git clang lldb clang-tidy clang-tools cppcheck - # Handle loader crap - - name: create loader directories - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_503 make create - - name: clean loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_503 make clean - - name: create mira directories - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_503 make create - - name: clean mira - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_503 make clean - # 5.03 Support - - name: make 5.03 loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_503 MIRA_CHECKS=TRUE make - - name: make 5.03 elf - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_503 ADD_GIT_HASH=TRUE MIRA_CHECKS=TRUE make - - name: Upload 5.03 loader - uses: actions/upload-artifact@v2 - with: - name: MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_503.bin - path: loader/build/MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_503.bin - - name: Upload 5.03 elf - uses: actions/upload-artifact@v2 - with: - name: Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_503.elf - path: kernel/build/Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_503.elf diff --git a/.github/workflows/Orbis505.yml b/.github/workflows/Orbis505.yml deleted file mode 100644 index 9cfa6981..00000000 --- a/.github/workflows/Orbis505.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Orbis505 - -on: - push: - branches: [ master, develop ] - pull_request: - branches: [ master, develop ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - # Checkout the repository - - uses: actions/checkout@v2 - # Install required stuff needed to build Mira - - name: preinstall - run: sudo apt install build-essential git clang lldb clang-tidy clang-tools cppcheck - # Handle loader crap - - name: create loader directories - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_505 make create - - name: clean loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_505 make clean - - name: create mira directories - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_505 make create - - name: clean mira - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_505 make clean - # 5.05 Support - - name: make 5.05 loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_505 MIRA_CHECKS=TRUE make - - name: make 5.05 elf - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_505 ADD_GIT_HASH=TRUE MIRA_CHECKS=TRUE make - - name: Upload 5.05 loader - uses: actions/upload-artifact@v2 - with: - name: MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_505.bin - path: loader/build/MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_505.bin - - name: Upload 5.05 elf - uses: actions/upload-artifact@v2 - with: - name: Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_505.elf - path: kernel/build/Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_505.elf diff --git a/.github/workflows/Orbis620.yml b/.github/workflows/Orbis620.yml deleted file mode 100644 index d5ce193d..00000000 --- a/.github/workflows/Orbis620.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Orbis620 - -on: - push: - branches: [ master, develop ] - pull_request: - branches: [ master, develop ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - # Checkout the repository - - uses: actions/checkout@v2 - # Install required stuff needed to build Mira - - name: preinstall - run: sudo apt install build-essential git clang lldb clang-tidy clang-tools cppcheck - # Handle loader crap - - name: create loader directories - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_620 make create - - name: clean loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_620 make clean - - name: create mira directories - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_620 make create - - name: clean mira - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_620 make clean - # 6.20 Support - - name: make 6.20 loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_620 MIRA_CHECKS=TRUE make - - name: make 6.20 elf - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_620 MIRA_CHECKS=TRUE make - - name: Upload 6.20 loader - uses: actions/upload-artifact@v2 - with: - name: MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_620.bin - path: loader/build/MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_620.bin - - name: Upload 6.20 elf - uses: actions/upload-artifact@v2 - with: - name: Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_620.elf - path: kernel/build/Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_620.elf diff --git a/.github/workflows/Orbis672.yml b/.github/workflows/Orbis672.yml deleted file mode 100644 index 930f8045..00000000 --- a/.github/workflows/Orbis672.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Orbis672 - -on: - push: - branches: [ master, develop ] - pull_request: - branches: [ master, develop ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - # Checkout the repository - - uses: actions/checkout@v2 - # Install required stuff needed to build Mira - - name: preinstall - run: sudo apt install build-essential git clang lldb clang-tidy clang-tools cppcheck - # Handle loader crap - - name: create loader directories - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_672 make create - - name: clean loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_672 make clean - - name: create mira directories - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_672 make create - - name: clean mira - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_672 make clean - # 6.72 Support - - name: make 6.72 loader - run: cd loader; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_672 MIRA_CHECKS=TRUE make - - name: make 6.72 elf - run: cd kernel; MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_672 ADD_GIT_HASH=TRUE MIRA_CHECKS=TRUE make - - name: Upload 6.72 loader - uses: actions/upload-artifact@v2 - with: - name: MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_672.bin - path: loader/build/MiraLoader_Orbis_MIRA_PLATFORM_ORBIS_BSD_672.bin - - name: Upload 6.72 elf - uses: actions/upload-artifact@v2 - with: - name: Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_672.elf - path: kernel/build/Mira_Orbis_MIRA_PLATFORM_ORBIS_BSD_672.elf diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 00000000..34240092 --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,80 @@ +name: C/C++ CI + +on: [push] + +jobs: + build-ubuntu: + + runs-on: ubuntu-latest + + steps: + - name: Set up Clang + uses: egor-tensin/setup-clang@v1 + with: + version: 13 + platform: x64 + - uses: actions/checkout@v1 + - name: Install Pre-Reqs + run: sudo apt update && sudo apt install lld + - name: Download and install OOSDK + run: mkdir /home/runner/toolchain && pushd /home/runner/toolchain && wget https://github.com/OpenOrbis/OpenOrbis-PS4-Toolchain/releases/download/v0.5.2/v0.5.2.tar.gz && tar -zxvf v0.5.2.tar.gz && mv OpenOrbis/PS4Toolchain/* /home/runner/toolchain && rm -rf OpenOrbis && export OO_PS4_TOOLCHAIN=/home/runner/toolchain && echo "OO_PS4_TOOLCHAIN=/home/runner/toolchain" >> $GITHUB_ENV && popd + #- name: configure176 + # run: export MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_176 && mkdir build176 && cd build176 && cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER=clang-13 -DCMAKE_CXX_COMPILER=clang++-13 -DMIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_176 -G "Unix Makefiles" .. && cd .. + #- name: configure405 + # run: mkdir build405 && cd build405 && cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER=clang-13 -DCMAKE_CXX_COMPILER=clang++-13 -DMIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_405 -G "Unix Makefiles" .. && cd .. + #- name: configure455 + # run: mkdir build455 && cd build455 && cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER=clang-13 -DCMAKE_CXX_COMPILER=clang++-13 -DMIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_455 -G "Unix Makefiles" .. && cd .. + #- name: configure474 + # run: mkdir build474 && cd build474 && cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER=clang-13 -DCMAKE_CXX_COMPILER=clang++-13 -DMIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_474 -G "Unix Makefiles" .. && cd .. + #- name: configure501 + # run: mkdir build501 && cd build501 && cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER=clang-13 -DCMAKE_CXX_COMPILER=clang++-13 -DMIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_501 -G "Unix Makefiles" .. && cd .. + #- name: configure505 + # run: mkdir build505 && cd build505 && cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER=clang-13 -DCMAKE_CXX_COMPILER=clang++-13 -DMIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_505 -G "Unix Makefiles" .. && cd .. + #- name: configure620 + # run: mkdir build620 && cd build620 && cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER=clang-13 -DCMAKE_CXX_COMPILER=clang++-13 -DMIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_620 -G "Unix Makefiles" .. && cd .. + #- name: configure650 + # run: mkdir build650 && cd build650 && cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER=clang-13 -DCMAKE_CXX_COMPILER=clang++-13 -DMIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_650 -G "Unix Makefiles" .. && cd .. + - name: configure672 + run: mkdir build672 && cd build672 && cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER=clang-13 -DCMAKE_CXX_COMPILER=clang++-13 -DMIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_672 -G "Unix Makefiles" .. && cd .. + #- name: configure755 + # run: mkdir build755 && cd build755 && cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER=clang-13 -DCMAKE_CXX_COMPILER=clang++-13 -DMIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_755 -G "Unix Makefiles" .. && cd .. + #- name: build176 + # run: cmake --build build176 + #- name: build405 + # run: cmake --build build405 + #- name: build455 + # run: cmake --build build455 + #- name: build474 + # run: cmake --build build474 + #- name: build501 + # run: cmake --build build501 + #- name: build505 + # run: cmake --build build505 + #- name: build620 + # run: cmake --build build620 + #- name: build650 + # run: cmake --build build650 + - name: build672 + run: cmake --build build672 + #- name: build755 + # run: cmake --build build755 + - name: upload mira binaries + uses: actions/upload-artifact@v2 + with: + name: Binaries + path: | + build176/loader/loader.bin + build405/loader/loader.bin + build455/loader/loader.bin + build474/loader/loader.bin + build501/loader/loader.bin + build505/loader/loader.bin + build620/loader/loader.bin + build650/loader/loader.bin + build672/loader/loader.bin + build672/example_trainer/example_trainer.prx + build672/tests/tests.EBOOT.BIN + build672/daemon/daemon.prx + build672/mira_module/mira_module.prx + build755/loader/loader.bin + diff --git a/.gitignore b/.gitignore index ecc8bc13..97fc952d 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ project.log report.tasks strace_out maneja/** +.vscode/* +*.prx +*.oprx \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index 15a6f4ca..00000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "configurations": [ - { - "name": "Mira", - "includePath": [ - "${workspaceFolder}/kernel/**", - "${workspaceFolder}/kernel/src", - "${workspaceFolder}/external/freebsd-headers/include", - "${workspaceFolder}/external" - ], - "defines": [ - "_KERNEL", - "MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_505", - "__LP64__=1", - "_M_X64", - "__amd64__", - "_DEBUG", - "__BSD_VISIBLE", - "__FreeBSD__", - "FLATCC_USE_GENERIC_ALIGNED_ALLOC", - "MIRA_UNSUPPORTED_PLATFORMS" - ], - "compilerPath": "/usr/bin/clang", - "cStandard": "c11", - "cppStandard": "c++11", - "intelliSenseMode": "clang-x64" - }, - { - "name": "MiraLoader", - "includePath": [ - "${workspaceFolder}/kernel/**", - "${workspaceFolder}/loader", - "${workspaceFolder}/external/freebsd-headers/include" - ], - "defines": [ - "_KERNEL", - "MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_505", - "__LP64__=1", - "_M_X64", - "__amd64__", - "_DEBUG", - "__BSD_VISIBLE", - "__FreeBSD__", - "MIRA_UNSUPPORTED_PLATFORMS" - ], - "compilerPath": "/usr/bin/clang", - "cStandard": "c11", - "cppStandard": "c++11", - "intelliSenseMode": "clang-x64" - }, - { - "name": "Daemon", - "includePath": [ - "${workspaceFolder}/daemon/src", - "${env:OO_PS4_TOOLCHAIN}/include", - "${env:OO_PS4_TOOLCHAIN}/include/c++/v1", - "${workspaceFolder}/daemon/src/External/include" - ], - "defines": [ - "_DEBUG", - "PS4", - "__FreeBSD__", - "__BSD_VISIBLE" - ], - "compilerPath": "/usr/bin/clang++", - "cStandard": "c11", - "cppStandard": "c++14", - "intelliSenseMode": "clang-x64" - }, - { - "name": "Maneja", - "includePath": [ - "${workspaceFolder}/maneja/Source/**", - "${env:OO_PS4_TOOLCHAIN}/include", - "${env:OO_PS4_TOOLCHAIN}/include/c++/v1" - ], - "defines": [ - "_DEBUG", - "PS4" - ], - "compilerPath": "/usr/bin/clang++", - "cStandard": "c11", - "cppStandard": "c++14", - "intelliSenseMode": "clang-x64" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 6deec11c..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Launch", - "program": "${workspaceFolder}/maneja/Build/maneja_pc.elf", - "args": [], - "cwd": "${workspaceFolder}/maneja" - } - ] -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index c670b9a5..00000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "version": "2.0.0", - "options": { - "env": { - "platform": "MIRA_PLATFORM_ORBIS_BSD_505", - "checks": "" - } - }, - "tasks": [ - { - "label": "Build Mira", - "type": "shell", - - "command": "MIRA_PLATFORM=$platform make clean;MIRA_PLATFORM=$platform make create;MIRA_PLATFORM=$platform MIRA_CHECKS=$checks pvs-studio-analyzer trace -- make", - "group": "build", - "problemMatcher": [ - "$gcc" - ], - "options": { - "cwd": "${workspaceFolder}/kernel" - }, - "dependsOn": [ "Build MiraLoader" ] - }, - { - "label": "Build MiraLoader", - "type": "shell", - "command": "MIRA_PLATFORM=$platform make clean;MIRA_PLATFORM=$platform make create;MIRA_PLATFORM=$platform MIRA_CHECKS=$checks make", - "group": "build", - "problemMatcher": [ - "$gcc" - ], - "options": { - "cwd": "${workspaceFolder}/loader" - } - }, - { - "label": "Build protobuf files", - "type": "shell", - "command": "python3 ./scripts/build_proto.py --inputDir=./external", - "group": "build", - "problemMatcher": [ - "$gcc" - ] - }, - { - "label": "Build Flatbuffers", - "type": "shell", - "command": "flatc --cpp rpc.fbs; flatc --cpp filemanager.fbs", - "group": "build", - "problemMatcher": [ - "$gcc" - ], - "options": { - "cwd": "${workspaceFolder}/daemon/src/External/flatbuffers" - } - }, - { - "label": "Build Daemon", - "type": "shell", - "command": "make clean; make", - "group": "build", - "problemMatcher": [ - "$gcc" - ], - "options": { - "cwd": "${workspaceFolder}/daemon" - } - }, - { - "label": "Build Maneja (PC)", - "type": "shell", - "command": "make pc", - "group": "build", - "problemMatcher": [ - "$gcc" - ], - "options": { - "cwd": "${workspaceFolder}/maneja" - } - }, - { - "label": "Build Maneja (PS4)", - "type": "shell", - "command": "make ps4", - "group": "build", - "problemMatcher": [ - "$gcc" - ], - "options": { - "cwd": "${workspaceFolder}/maneja" - } - } - ] -} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..d35aa8ab --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,92 @@ +cmake_minimum_required(VERSION 3.20) + +# Set verbosity +set(CMAKE_VERBOSE_MAKEFILE OFF) + +# set the project name +project(mira-project) + +# Set the firmware version +if (MIRA_PLATFORM) +else() + message("MIRA_PLATFORM not defined, defaulting to 672") + set(MIRA_PLATFORM MIRA_PLATFORM_ORBIS_BSD_672) +endif() + +if (NOT "" STREQUAL "$ENV{MIRA_PLATFORM}") + message("overriding build by environment variable for MIRA_PLATFORM=$ENV{MIRA_PLATFORM}") + set(MIRA_PLATFORM $ENV{MIRA_PLATFORM}) +endif() + +# Display some output to the user +message("Configuring for MIRA_PLATFORM=${MIRA_PLATFORM}") + +# Enable static analysis checking +set(MIRA_CHECKS False) +set(OOSDK_FOUND False) + + +# mira-project's required build order +# There are dependencies that require certain things to be pre-built +# +# /kernel +# - Dep: trainer_loader +# +# /loader +# - Dep: kernel +# +# /mira_module (OOSDK dep, none local) +# /daemon (OOSDK dep, none local) + +# If we have MIRA_CHECKS on our environment variable, then we enable it in CMAKE +if (EXISTS "$ENV{MIRA_CHECKS}") + set(MIRA_CHECKS True) +endif() + +# If the OO_PS4_TOOLCHAIN environment variable is found, set a CMake variable with the same name +if (EXISTS "$ENV{OO_PS4_TOOLCHAIN}") + set(OO_PS4_TOOLCHAIN $ENV{OO_PS4_TOOLCHAIN}) + set(OOSDK_FOUND True) +endif() + +# Spit out a message if we have static analysis enabled +if (MIRA_CHECKS EQUAL True) + message("MIRA_CHECKS is enabled, enabling static analysis.") +endif() + +# Check to see if we found the OpenOrbis Toolchain +if (EXISTS "$ENV{OO_PS4_TOOLCHAIN}") + message("OpenOrbis SDK found, building extra libraries...") + + # Build the userland common module which gets injected into each process + add_subdirectory(mira_module) + + # Trainer example + add_subdirectory(example_trainer) + + # Make mira_module a dependency of example_trainer + add_dependencies(example_trainer mira_module) + + # Build the daemon + add_subdirectory(daemon) + + # Make the standalone tests + add_subdirectory(tests) +else() + message("OpenOrbis SDK is not found, extra libraries is skipped ...") +endif() + +# This is required for all other steps to succeeed +add_subdirectory(trainer_loader) + +# Kernel depends on trainer_loader +add_subdirectory(kernel) + +# Make trainer_loader a dependency of kernel +add_dependencies(kernel trainer_loader) + +# Loader depends on kernel +add_subdirectory(loader) + +# Make kernel a dependency of loader +add_dependencies(loader kernel) diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md new file mode 100644 index 00000000..e735f043 --- /dev/null +++ b/CONTRIBUTION.md @@ -0,0 +1,18 @@ +Shamelessly Stolen and Modified from RPCS3's Repo: https://github.com/RPCS3/rpcs3/wiki/coding-style + +We recommend to follow these guidelines when writing code for Mira-Project. They aren't very strict rules since we want to be flexible and we understand that under certain circumstances some of them can be counterproductive. Just try to follow as many of them as possible: + +### General coding style +* Variable naming: *Prefix + CamelCase* + * Globals: _g__* + * Class members: _m__* + * Scoped: _s__* + * Looped: _l__* + * Constants: _c__* +* Template parameter names: *CamelCase*, or just T, U, V... +* Avoid `#defines`, use constant variables instead, preferrably in an enum class. +* Put curly-brackets (`{` and `}`) on the next line. +* Eliminate all compiler warnings from your code. +* Comment *every* hack you do, *every* snippet you comment out and *every* improvable code. +* If you have to comment or place a commented code snippet, include the reasons to do that in the comment. +* Ensure that every source file you modify has the newline at the end of file. Every line ends with "newline" and the end of file must have "newline" too, GitHub usually warns about it. \ No newline at end of file diff --git a/CppCheckSuppressions.txt b/CppCheckSuppressions.txt new file mode 100644 index 00000000..e69de29b diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..808c04b8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +FROM ubuntu:focal + +# Version to build +ENV MIRA_PLATFORM MIRA_PLATFORM_ORBIS_BSD_672 + +# Install key +RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - + +# Install dependencies +RUN apt-get -qq update && \ + apt-get install -qqy --install-recommends \ + ca-certificates \ + autoconf automake cmake dpkg-dev file git make patch \ + libc-dev libc++-dev libgcc-10-dev libstdc++-10-dev \ + dirmngr gnupg2 lbzip2 wget xz-utils libtinfo5 clang-13 lldb-13 lld-13 git tar && \ + rm -rf /var/lib/apt/lists/* + +# TODO: Prep OOSDK Toolchain +RUN mkdir /toolchain && cd /toolchain && wget https://github.com/OpenOrbis/OpenOrbis-PS4-Toolchain/releases/download/v0.5.2/v0.5.2.tar.gz && \ + tar -zxvf v0.5.2.tar.gz && mv OpenOrbis/PS4Toolchain/* /toolchain && rm -rf /toolchain/OpenOrbis && \ + export OO_PS4_TOOLCHAIN=/toolchain + +# Build Mira +RUN export MIRA_PLATFORM=${MIRA_PLATFORM} && mkdir /build && cd /build && \ + git clone https://github.com/kiwidoggie/mira-project.git && \ + /usr/local/bin/cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DMIRA_PLATFORM=${MIRA_PLATFORM} -H/build/mira-project -B/build/mira-project/build -G "Unix Makefiles" \ + /usr/local/bin/cmake --build /build/mira-project --config Debug --target clean -j 34 -- \ No newline at end of file diff --git a/README.md b/README.md index f6e7d2e2..5df760ae 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ The Mira Project is a set of tools that grants you more power and control over your jailbroken Playstation 4. It is the result of all the hard work by the OpenOrbis team. -It works differently to the custom firmware experience on Playstation 3, where CFW would be installed on the system via modified PUP files (e.g. Rebug), however once the framework is installed and ran it gives users the same functionality they were previously used to. +It works differently to the custom firmware experience on Playstation 3, where CFW would be installed on the system via modified PUP files (e.g. Rebug), however once the framework is installed and ran it gives users the same functionality they were previously used to. This can be installed by exploiting specififc system applications to load the kernel exploit and load Mira (Persistence Boot), as well as being ran from WebKit. If you would like to contribute join us on [Open Orbis Discord], it is the only location where you can find the official project. @@ -15,84 +15,54 @@ If you would like to contribute join us on [Open Orbis Discord], it is the only |5.01|![](https://github.com/OpenOrbis/mira-project/workflows/Orbis501/badge.svg)| |5.03|![](https://github.com/OpenOrbis/mira-project/workflows/Orbis503/badge.svg)| |5.05|![](https://github.com/OpenOrbis/mira-project/workflows/Orbis505/badge.svg)| -|6.20|WIP| +|6.20|![](https://github.com/OpenOrbis/mira-project/workflows/Orbis620/badge.svg)| |6.72|![](https://github.com/OpenOrbis/mira-project/workflows/Orbis672/badge.svg)| +|7.00|WIP| +|7.55|WIP| -# New Features! +# Current Features +## Kernel - Homebrew Enabler (HEN) + - Trainer Support (Thanks theorywrong) + - Device driver for kernel extensions + +## Daemon + - RPC + - Debugger + - File Manager + +## Loader + - All modules are embedded into the loader + +# Planned Features + +## Kernel - Emulated Registry (EmuReg) - Emulated NVS (EmuNVS) - Kernel Debugger - Remote GDB - System-level FUSE implementation (Experimental, WIP) - - Load sprx modules + IAT + Function Hooking (Thanks theorywrong) + - Kernel Soft Reboot + - FakeDex Support + - Linux loader -You can also: +## Daemon - Mount and decrypt local gamesaves (Thanks ChendoChap) (WIP) - - Transfer files to and from the harddrive - - Implement your own kernel plugins (RPC using protobuf) - - Implement your own userland trainers (hooks included!) - - Dump your HDD encryption keys - - A bunch of other stuff + - Implement your own dynamically loaded plugins (RPC using protobuf) + - Substitute hooking library + - Dumping per-console keys + - Update Removal + - Game dumping and decryption + - Remote registry + - Remote NVS -### Contributors +## Trainers + - SpoofNP (Fake NP for LAN usage) -This project would not be possible without these people (no paticluar order): +# Installation -* [kiwidog] - Developer -* [SpecterDev] - Developer -* [flatz] - Developer (Code, writeups, non-stop help we <3 u flatz) -* [CrazyVoid] - Developer (Loader/self/SDK help, overall general help, OO moderator) -* [theorywrong] - Developer (Substitute, OverlayFS, general) -* [SiSTR0] - Developer (HEN support, general) -* [SocraticBliss] - Developer (HEN support, general) -* [valentinbreiz] - Developer (Mira Companion App v1) -* [Seremo] - Developer (Mira Companion App v2, Log plugin) -* [Al-Azif] - Developer (5.05 lead maintainer, general) -* [z80] - Developer (5.05 maintainer) -* [balika011] - Developer (Fixing userland elf loader entry point, general developer) -* [Zer0xFF] - Developer (OverlayFS, general) -* [CelesteBlue] - Developer (Bugfixes, plugins) -* [Joonie] - Developer (Offsets porting 5.01/5.05) -* [AlexAltea] - Low level and kernel help (go check out [Orbital Emulator]) -* [qwertyoruiop] - Security (4.55-5.05 kernel exploits) -* CTurt - Security (Initial payload PS4 SDK and 1.76 kernel exploit) -* [m0rph3us1987] - Developer (Code examples, kernel SDK, overall general help) -* [eeply] - Developer (UART) -* [zecoxao] - RE (4.74 Port) -* [aerosoul] - Developer (Everything elf related, loaders, etc) -* [maxton] - Developer (Everything pkg related, etc) -* [ChendoChap] - RE (Bug hunting, general kernel help) -* [sugarleaf] - Initial 4.55 private exploit, inital help with Mira dev (retired/left) -* [kozarovv] - RE (4.05 offsets) -* [LM] - RE (Research on System-Library-Loading), assembler and linker script help -* [TheFlow] - RE -* [samsepi0l] - Offset Porting -* [xvortex] - Original VTX-Hen -* [2much4u] - Ptrace patches -* [golden] - Ptrace patches, rpc ideas -* [idc] - Developer -* [lordfriky] - MacOS support and script fixes -* [ethylamine] - Developer - -### Special Thanks -* [bigboss] - liborbis with examples and orbisdev (and complaining a lot) -* [rogero] - Original 5.01 testing -* [AbkarinoMHM] - Original 5.01 testing -* [wildcard] - General questions, and hardware help -* [frangarcj] - orbisdev sdk, musl, C++ support -* [masterzorag] - orbisdev sdk, musl, C++ support -* [fjtrujy] - orbisdev sdk, musl, C++ support -* [Anon #1] - Developer (Code, Non-stop help, <3 thx bruv) -* [Anon #2] - Developer (Code, Non-stop help, gl with job!) -* [Anon #3] - Security (Future proofing design) -* [Anon #4] - Developer (Ideas from Vita) -* [Anon #5] - Security (Software and hardware) - -### Installation - -#### Checking out repository +## Checking out repository In order to start development on the mira-project, you will need a few components installed. * clang * clang-tidy @@ -102,148 +72,47 @@ In order to start development on the mira-project, you will need a few component * ld (or lld.ld) * git * python3 (3.6.9 at time of writing, but any newer version should work) +* cmake These can be installed (on Ubuntu, other platforms may vary) by using the command(s): -`sudo apt install git build-essential clang lldb clang-tidy clang-tools cppcheck` +`sudo apt install git build-essential clang lldb clang-tidy clang-tools cppcheck git python3 cmake` -#### Cloning the repository +## Cloning the repository Cloning the repository is easily done by: `git clone https://github.com/OpenOrbis/mira-project.git` -#### Protobuf files -The RPC messaging system leverages protobuf in order to easily expand and add cross-language RPC support. This involves 2 major components for the default build. Due to previous dependencies, we are not using the C++ version of protobuf due to not having a full STL runtime in the kernel (it was too much work/effort) so instead we are leveraging the [protobuf-c] project. - -##### Installing protobuf-c -Installing protobuf-c should only need to be done once, there is support for proto3 files at this time and should not be an issue (compared to previous which only supported proto2). - -You can follow the protobuf build instructions located [here](https://github.com/protobuf-c/protobuf-c#building) - -##### Building the protobuf file definitions + fixing them -Currently there is a script that will handle *most* of the work required for building new protobuf files. From the *ROOT* of the cloned directory (mira-project/) you can use the provided python script for generating new protobuf files. - -`python3 ./scripts/build_proto.py --inputDir=./external` - -By default the script will only run in the local directory it was called from. This behavior can be changed with command line argument overrides: - -`--inputDir=` -`--outputDir=` (otherwise use the input directory as default) -`--miraDir=` -`--noMvPbcFiles=` (allows you to skip the move of the protobuf files, default: false) - -The vscode `tasks.json` can be configured to do this automatically in the project repository - -``` -{ - "label": "Build protobuf files", - "type": "shell", - "command": "python3 ./scripts/build_proto.py --inputDir=./external", - "group": "build", - "problemMatcher": [ - "$gcc" - ] - } -``` - -The script takes care of generating, fixing, and moving the .c/.h files, as well as the C# (.cs) counterparts for use with the MiraLib/API. - -##### Moving and fixing the .c includes -This part has not been scripted yet, because if someone were to add a new proto file, they would have to manually update the script. - -###### (Optional) Moving the protobuf files manually -If you decide to not move the protobuf files automatically with the script you can still do it manually (or you can move your own ones). - -|File|Intended Location| -| ------ | ------ | -|`external/debugger_structs.pb-c.(c/h)` | `src/Plugins/Debugger` | -|`external/debugger.pb-c.(c/h)` | `src/Plugins/Debugger` | -|`external/filemanager.pb-c.(c/h)` | `src/Plugins/FileManager` | -|`external/rpc.pb-c.(c/h)` | `src/Messaging/Rpc` | - -###### (Optional) Manually fix the C# protobuf files -If you did not use the python script, the C# files will not be automatically fixed for you. There is an issue with modern versions of C# and the output that protobuf generates for .cs files. - -By default protobuf generates the C# files looking like so (which cause a build error on .net core) -``` -[global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { - uint tag; - while ((tag = input.ReadTag()) != 0) { - switch(tag) { - default: - if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { - return; - } - break; - case 10: { - Message = input.ReadString(); - break; - } - } - } - } -``` - -This needs a very simple fix in order to build in modern .net core, a line change from: -``` -if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { - return; - } -``` - -to - -``` -_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); - break; -``` - -And you can include this anywhere in your C# project and begin to use extension methods to add them to MiraConnection for usage in your own application. - -#### Source code layout +## Source code layout The current mira-project repository is self-contained, meaning everything the project depends on should be within the repo itself. Here is a layout of the source repository (all from root of mira-project directory) | Directory | Purpose | | ------ | ------ | | `build` | Working/output build files, as well as final executables and payloads | +| `daemon` | The userland daemon that handles most background tasks for Mira | | `docs` | Documentation about PlayStation 4/Mira twiddly bits | -| `external` | External resources, contains `freebsd-headers` (*MODIFIED FOR KERNEL/PS4 USAGE*), `hde64` for disassembly, `protobuf-c` for protobuf handling, `*.proto` protobuf files to be generated into source | +| `external` | External resources, contains `freebsd-headers` (*MODIFIED FOR KERNEL/PS4 USAGE*), `hde64` for disassembly, `mira` for Mira headers/code shared across multiple projects | +| `kernel` | The kernel component of Mira | | `loader` | This is the MiraLoader which is required to *properly* relocate the main ELF in kernel memory and execute in a new kernel thread | -| (Optional/Missing) `protobuf-test` | Test project for protobuf serialization on Linux | +| `mira_module` | This is a prx that will be loaded into every created process, it will contain common code for trainers and interfacing with the kernel driver | | `scripts` | Build/Helper scripts | -| `kernel` | The kernel component of Mira | -| `kernel/src` | Main source code | -| `kernel/src/Boot` | Contains everything needed for booting Mira/patching consoles (firmware specific implementations) | -| `kernel/src/Driver` | The device driver code (used for user process ioctl, thanks TW for implementing) | -| `kernel/src/External` | Source files for those headers in `external` | -| `kernel/src/Messaging` | Message manager (protobuf handling and RPC) | -| `kernel/src/OrbisOS` | PlayStation 4 specific code and utilities | -| `kernel/src/Plugins` | All kernel mode plugins + RPC handlers | -| (Deprecated) `kernel/src/Trainers` | Trainer launcher source | -| `kernel/src/Utils` | General *Mira* based utilities for working in kernel (kernel function resolving, syscall wrappers, etc) | +| `tests` | Test application to ensure that mira_module, and the kernel driver ioctl's are operating correctly | +| `trainer_loader` | Stub that gets injected and ran on every new process start which will ioctl to Mira's device driver to load trainers | -### Plugins - -Mira provides a plugin framework that can run in kernel mode (userland is soon, thanks to TW!), it provides a stable framework for startup, shutdown, suspend, resume in order to ensure clean operation of Mira. These paths are within the `/kernel` directory - -| Plugin | Directory | -| ------ | ------ | -| Debugger | src/plugins/Debugger | -| (WIP) Emulated Registry | src/plugins/EmuRegistry | -| Fake PKG | src/plugins/FakePKG | -| Fake Self | src/plugins/FakeSELF | -| File Manager | src/plugins/FileManager | -| (WIP) Fuse | src/plugins/FuseFS | -| Log Server | src/plugins/LogServer | -| (WIP) OverlayFS (OrbisAFR) | src/plugins/OverlayFS | -| (WIP) Substitute | src/plugins/Substitute | - -### Development +## Development Want to contribute? Great! There is no set limit on contributors and people wanting to help out in any way! Join the [OpenOrbis discord](https://discord.gg/GQr8ydn) and have knowledge of C/C++ and FreeBSD or unix-like operating systems, web design and programming, rust-lang, content creator (youtube, twitch), or artist, or just want to find something to help out with like documentation, hosting, etc, kernel experience is a plus but not required by any means. -#### Building from source +### Building from source +If using and IDE such as VSCode, it should automatically pick up and generate the files for use with CMake. If not you can use CMake to generate the project for you by doing + +``` +mkdir mira-build +cd mira-build +cmake -G "Unix Makefiles" ../mira-project +make +``` + After following the instructions on cloning the repository and generating the protobuf files, you should be ready to build Mira from source. It was designed to be as easy as possible to build with the provided makefiles. Each makefile (for MiraLoader, and Mira itself) follow a specific format due to compilers ignoring most changes in header (.h) files causing issues down the line. @@ -288,96 +157,9 @@ There is a list of available platforms that Mira can be configured with located |`MIRA_PLATFORM_ORBIS_BSD_620`| (Unsupported) 6.20 | |`MIRA_PLATFORM_ORBIS_BSD_650`| (Unsupported) 6.50 | |`MIRA_PLATFORM_ORBIS_BSD_672`| (Supported) 6.72 | +|`MIRA_PLATFORM_ORBIS_BSD_700`| (Unsupported) 7.00 | +|`MIRA_PLATFORM_ORBIS_BSD_755`| (Unsupported) 7.55 | -Provided are some VSCode `tasks.json` formats: - -``` -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Build Mira", - "type": "shell", - "command": "cd kernel;make clean;make create;make", - "group": "build", - "problemMatcher": [ - "$gcc" - ] - }, - { - "label": "Build MiraLoader", - "type": "shell", - "command": "cd loader;make clean;make create;make", - "group": "build", - "problemMatcher": [ - "$gcc" - ] - }, - { - "label": "Build protobuf files", - "type": "shell", - "command": "python3 ./scripts/build_proto.py --inputDir=./external", - "group": "build", - "problemMatcher": [ - "$gcc" - ] - } - ] -} -``` - -And here is an example VSCode `c_cpp_properties.json` -``` -{ - "configurations": [ - { - "name": "Mira", - "includePath": [ - "${workspaceFolder}/**", - "${workspaceFolder}/src", - "${workspaceFolder}/external/freebsd-headers/include" - ], - "defines": [ - "_KERNEL", - "MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_501", - "__LP64__=1", - "_M_X64", - "__amd64__", - "_DEBUG", - "__BSD_VISIBLE", - "MIRA_UNSUPPORTED_PLATFORMS" - ], - "compilerPath": "/usr/bin/clang", - "cStandard": "c11", - "cppStandard": "c++11", - "intelliSenseMode": "clang-x64" - }, - { - "name": "MiraLoader", - "includePath": [ - "${workspaceFolder}/**", - "${workspaceFolder}/loader", - "${workspaceFolder}/external/freebsd-headers/include" - ], - "defines": [ - "_KERNEL", - "MIRA_PLATFORM=MIRA_PLATFORM_ORBIS_BSD_501", - "__LP64__=1", - "_M_X64", - "__amd64__", - "_DEBUG", - "__BSD_VISIBLE", - "MIRA_UNSUPPORTED_PLATFORMS" - ], - "compilerPath": "/usr/bin/clang", - "cStandard": "c11", - "cppStandard": "c++11", - "intelliSenseMode": "clang-x64" - } - ], - "version": 4 -} -``` #### Firmware porting guide Lets say you are an eager developer, even a newbie that wants to try and contribute in some way or form to porting to a firmware that is not under active support. Here's the steps you would need to accomplish new builds *from scratch*. We will start by adding a non-existent firmware and work our way from that. @@ -388,47 +170,92 @@ Lets say you are an eager developer, even a newbie that wants to try and contrib Lets assume our firmware is `8.88` found in the PlayStation 4 System Software menu. -1. Add your new firmware to `src/Boot/Config.hpp` you will see a bunch of defines already there, add your firmware in the correct version order +1. Add your new firmware to `external/mira/Kernel/Boot/Config.hpp` you will see a bunch of defines already there, add your firmware in the correct version order a. **#define MIRA_PLATFORM_ORBIS_BSD_888 888** 2. Fix any structure changes for the kernel in freebsd-headers. You should compare against what's already there and add fields that have been added via a. **#if MIRA_PLATFORM==MIRA_PLATFORM_ORBIS_BSD_888** b. *HINT:* These are usually done in `struct proc`, `struct thread`, `struct ucred` if applicable, located in `exernal/freebsd-headers/include`. -3. Add a new static function in `src/Boot/Patches.hpp` with your pre-boot patches, this will be called after MiraLoader finishes and before Mira runs +3. Add a new static function in `kernel/src/Boot/Patches.hpp` with your pre-boot patches, this will be called both before MiraLoader and Mira launch a. **static void install_prerunPatches_888();** -4. Add your firmwares version to the case within `install_prePatches` in `src/Boot/Patches.cpp` +4. Add your firmwares version to the case within `install_prePatches` in `kernel/src/Boot/Patches.cpp` a. `case MIRA_PLATFORM_ORBIS_BSD_888: install_prerunPatches_888(); break;` -5. Next create a new file named `Patches888.cpp` inside of `src/Boot/Patches` directory (or copy an existing one and rename it) +5. Next create a new file named `Patches888.cpp` inside of `kernel/src/Boot/Patches` directory (or copy an existing one and rename it) 6. You must follow the same format as all of the other patch files, this involves including the `Patches.hpp` and defining the `install_prerunPatches_888()` function with all needed patches a. As new features are added, this will need to be updated for any kernel patches required, so far a baseline is Enable UART, Verbose Kernel Panics, Enable RWX mappings, Enable MAP_SELF, Patching copy(in/out)(str) checks, patching memcpy checks, patching ptrace checks, patching setlogin (for autolaunch check), patch mprotect to allow RWX, patching pfs signature checking, patching to enable debug rifs, patch to enable all logs to console, (newer fws: disable sceverifier, delayed panics) b. All patches are required for full functionality, but to get up and running only the rwx patches, copy(in/out)(str), memcpy, mprotect patches are needed (I think, someone correct documentation + send PR if wrong). -7. Add support to the MiraLoader by copying the newly finished `src/Boot/Patches.cpp` to `loader/src/Boot/Patches.cpp` and the new `src/Boot/Patches/Patches888.cpp` to `loader/src/Boot/Patches/Patches888.cpp` -8. Next would be to create a new kernel symbol file in `src/Utils/Kdlsym/Orbis888.hpp` or copy one from a supported platform (more offsets than what's probably needed) -9. Add support by modifying `src/Utils/Kdlsym.hpp` and adding either within `#if defined(MIRA_UNSUPPORTED_PLATFORMS)` before the `#endif` a line for your firmware file (make sure these are in numeric order) `#elif MIRA_PLATFORM==MIRA_PLATFORM_ORBIS_BSD_888 +7. Add support to the MiraLoader by copying the newly finished `kernel/src/Boot/Patches.cpp` to `loader/src/Boot/Patches.cpp` and the new `kernel/src/Boot/Patches/Patches888.cpp` to `loader/src/Boot/Patches/Patches888.cpp` +8. Next would be to create a new kernel symbol file in `external/mira/Kernel/Utils/Kdlsym/Orbis888.hpp` or copy one from a supported platform (more offsets than what's probably needed) +9. Add support by modifying `external/mira/Kernel/Utils/Kdlsym.hpp` and adding a line for your firmware file (make sure these are in numeric order) `#elif MIRA_PLATFORM==MIRA_PLATFORM_ORBIS_BSD_888 #include "Kdlsym/Orbis888.hpp"` 9. The next step would be finding all of the functions that Mira/MiraLoader use in the kernel... This is the most time consuming portion of this and will need to be verified before upstreamed. The easiest way to handle this is to try building (using the build instructions provided) you will get a **massive ton** of errors around `kdlsym` and it not being able to find errors. One of such errors are shown as such: ``` -src/External/protobuf-c.c: In function ‘protobuf_c_message_unpack’: src/Utils/Kdlsym.hpp:49:52: error: ‘kdlsym_addr_printf’ undeclared (first use in this function) #define kdlsym(x) ((void*)((uint8_t *)&gKernelBase[kdlsym_addr_ ## x])) ``` -10. (continued) This means if you break it down, that **printf** was undeclared, look in your kernel dump with a dissassembler of choice (Ghidra/IDA Preferred, untested with others such as Binary Ninja, Relyze) and get the offset from the start of the loading address for the function `printf` (Calculated by Function Address - Base Address of Kernel where it was dumped from) and add it to your `src/Utils/Kdlsym/Orbis888.hpp` with the line `#define kdlsym_addr_printf 0x` and repeat for all other build errors. +10. (continued) This means if you break it down, that **printf** was undeclared, look in your kernel dump with a dissassembler of choice (Ghidra/IDA Preferred, untested with others such as Binary Ninja, Relyze) and get the offset from the start of the loading address for the function `printf` (Calculated by Function Address - Base Address of Kernel where it was dumped from) and add it to your `external/mira/Kernel/Utils/Kdlsym/Orbis888.hpp` with the line `#define kdlsym_addr_printf 0x` and repeat for all other build errors. 11. Once complete you should have a full port to a new firmware completed (unless I missed a step/something unclear, create issue or fix + PR please) -### TODOs +### Contributors + +This project would not be possible without these people (no paticluar order): + +* [kiwidog] - Developer +* [SpecterDev] - Developer +* [flatz] - Developer (Code, writeups, non-stop help we <3 u flatz) +* [CrazyVoid] - Developer (Loader/self/SDK help, overall general help, OO moderator) +* [theorywrong] - Developer (Substitute, OverlayFS, general) +* [SiSTR0] - Developer (HEN support, general) +* [SocraticBliss] - Developer (HEN support, general) +* [valentinbreiz] - Developer (Mira Companion App v1) +* [Seremo] - Developer (Mira Companion App v2, Log plugin) +* [Al-Azif] - Developer (5.05 lead maintainer, general) +* [z80] - Developer (5.05 maintainer) +* [balika011] - Developer (Fixing userland elf loader entry point, general developer) +* [Zer0xFF] - Developer (OverlayFS, general) +* [CelesteBlue] - Developer (Bugfixes, plugins) +* [Joonie] - Developer (Offsets porting 5.01/5.05) +* [AlexAltea] - Low level and kernel help (go check out [Orbital Emulator]) +* [qwertyoruiop] - Security (4.55-5.05 kernel exploits) +* CTurt - Security (Initial payload PS4 SDK and 1.76 kernel exploit) +* [m0rph3us1987] - Developer (Code examples, kernel SDK, overall general help) +* [sleirsgoevy] - Developer +* [eeply] - Developer (UART) +* [zecoxao] - RE (4.74 Port) +* [aerosoul] - Developer (Everything elf related, loaders, etc) +* [therootlord] - Developer +* [maxton] - Developer (Everything pkg related, etc) (Rest In Peace) +* [ChendoChap] - RE, Development, Trainers (Bug hunting, general kernel help) +* [sugarleaf] - Initial 4.55 private exploit, inital help with Mira dev (retired/left) +* [kozarovv] - RE (4.05 offsets) +* [LM] - RE (Research on System-Library-Loading), assembler and linker script help +* [TheFlow] - RE +* [samsepi0l] - Offset Porting +* [xvortex] - Original VTX-Hen +* [2much4u] - Ptrace patches +* [golden] - Ptrace patches, rpc ideas +* [idc] - Developer +* [lordfriky] - MacOS support and script fixes +* [ethylamine] - Developer + - - Clean kernel rebooting support - - Web browser activation - - Fake Online (spoof for LAN usage) - - Game dumping and decryption - - FakeDEX support - - Linux loader - - Embedded builds into loader - - Remote registry +### Special Thanks +* [bigboss] - liborbis with examples and orbisdev (and complaining a lot) +* [rogero] - Original 5.01 testing +* [AbkarinoMHM] - Original 5.01 testing +* [wildcard] - General questions, and hardware help +* [frangarcj] - orbisdev sdk, musl, C++ support +* [masterzorag] - orbisdev sdk, musl, C++ support +* [fjtrujy] - orbisdev sdk, musl, C++ support +* [Anon #1] - Developer (Code, Non-stop help, <3 thx bruv) +* [Anon #2] - Developer (Code, Non-stop help, gl with job!) +* [Anon #3] - Security (Future proofing design) +* [Anon #4] - Developer (Ideas from Vita) +* [Anon #5] - Security (Software and hardware) -License +# License ---- GPLv3 @@ -481,4 +308,6 @@ GPLv3 [idc]: [lordfriky]: [ethylamine]: + [sleirsgoevy]: + [therootlord]: [Open Orbis Discord]: diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt new file mode 100644 index 00000000..33573ac9 --- /dev/null +++ b/daemon/CMakeLists.txt @@ -0,0 +1,47 @@ +# Default cmake version +cmake_minimum_required(VERSION 3.20) + +# Name of the project +project(daemon) + +set(CMAKE_VERBOSE_MAKEFILE OFF) + +# NOTE: By default this line is disabled +# You should compile this project by using +# mkdir build && cd build +# cmake -DCMAKE_TOOLCHAIN_FILE=$OO_PS4_TOOLCHAIN/oosdk.cmake .. +# cmake --build . +# +# Include all of the OO_PS4_TOOLCHAIN defaults +include (${CMAKE_SOURCE_DIR}/scripts/oosdk.cmake) + +# Enable assembly files +enable_language(ASM) + +# Not needed for library examples +# Set the SCE authentication id +set(PROJECT_AUTH_ID 0x3800000000000011) + +# Include the default source directory, add additional include paths here +include_directories(${PROJECT_SOURCE_DIR}/src) + +# Linked libraries +link_libraries(-lc -lkernel -lc++) + +# Get all source location +file(GLOB_RECURSE PROJECT_SOURCES ${PROJECT_SOURCE_DIR}/*.cpp ${PROJECT_SOURCE_DIR}/*.cc ${PROJECT_SOURCE_DIR}/*.cxx ${PROJECT_SOURCE_DIR}/*.h ${PROJECT_SOURCE_DIR}/*.hpp ${PROJECT_SOURCE_DIR}/*.hxx) + +# Prebuilt objects +set(PREBUILT_OBJS + ${OO_PS4_TOOLCHAIN}/lib/crtlib.o +) + +# Add our project +# NOTE: libraries use crtlib.o, executables use crt1.o +add_executable(${PROJECT_NAME} ${PROJECT_SOURCES} ${PREBUILT_OBJS} ) + +set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX) + +# Create the fself +set(MODULE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}) +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${OO_PS4_TOOLCHAIN}/bin/linux/create-fself -in=${MODULE_OUTPUT_PATH} -out=${MODULE_OUTPUT_PATH}.oelf --lib ${MODULE_OUTPUT_PATH}.prx --paid ${PROJECT_AUTH_ID}) diff --git a/daemon/Makefile b/daemon/Makefile index 094798f5..0691258f 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -1,8 +1,16 @@ +ifeq ($(PLATFORM),) +PLATFORM := PS4 +endif + +ifeq ($(PLATFORM),PS4) + # CHANGEME: Default Orbis Version ifeq ($(OO_PS4_TOOLCHAIN),) $(error OO_PS4_TOOLCHAIN not set) endif +endif + # Check to see if we are building in CI/Checking mode # Leave empty (erase TRUE) if disabling ifeq ($(MIRA_CHECKS),) @@ -35,6 +43,8 @@ endif # Source directory SRC_DIR := src +ifeq ($(PLATFORM),PS4) + # Include directory paths I_DIRS := -I"$(OO_PS4_TOOLCHAIN)/include" -I$(OO_PS4_TOOLCHAIN)/include/c++/v1 -I$(SRC_DIR)/External/include -I$(SRC_DIR) @@ -48,7 +58,7 @@ LIBS := -lc -lkernel -lc++ -lSceNet C_DEFS := -D_DEBUG -DPS4 -D__BSD_VISIBLE -D_BSD_SOURCE # C++ Flags -CFLAGS := -cc1 -triple x86_64-pc-freebsd-elf -munwind-tables $(I_DIRS) $(C_DEFS) -fuse-init-array -emit-obj +CFLAGS := -triple x86_64-pc-freebsd-elf -funwind-tables $(I_DIRS) $(C_DEFS) -fuse-init-array -femit-obj # Assembly flags SFLAGS := -m64 -nodefaultlibs -nostdlib @@ -56,6 +66,30 @@ SFLAGS := -m64 -nodefaultlibs -nostdlib # Linker flags # -Wl,--build-id=none -T $(SRC_DIR)/link.x --emit-relocs -gc-sections -nmagic --relocatable LFLAGS := -m elf_x86_64 -pie --script $(OO_PS4_TOOLCHAIN)/link.x --eh-frame-hdr $(L_DIRS) $(LIBS) $(OO_PS4_TOOLCHAIN)/lib/crt1.o +else + +# Include directory paths +I_DIRS := -I$(SRC_DIR)/External/include -I$(SRC_DIR) -I/home/kuser/.local/include + +# Library directory paths +L_DIRS := -L/home/kuser/grpc/cmake/build -L/home/kuser/grpc/cmake/build/third_party/protobuf + +# Included libraries +LIBS := -lssl -lcrypto -lprotobufd + +# C Defines +C_DEFS := -D_DEBUG + +# C++ Flags +CFLAGS := -ggdb -funwind-tables -fPIC $(I_DIRS) $(C_DEFS) + +# Assembly flags +SFLAGS := -m64 -nodefaultlibs -nostdlib + +# Linker flags +LFLAGS := -pie -fsanitize=address -fno-omit-frame-pointer $(L_DIRS) $(LIBS) + +endif # Compiler options. You likely won't need to touch these. UNAME_S := $(shell uname -s) @@ -86,8 +120,10 @@ TARGET = eboot.bin #Make Rules $(TARGET): pre-run $(OUT_DIR) $(ALL_OBJ) - $(LNK) $(ALL_OBJ) -o $(OUT_DIR)/$(PROJ_NAME).elf $(LFLAGS) + $(CPPC) -std=c++17 -ggdb $(ALL_OBJ) -o $(OUT_DIR)/$(PROJ_NAME).elf $(LFLAGS) +ifeq ($(PLATFORM),PS4) $(OO_PS4_TOOLCHAIN)/bin/$(OS_NAME)/create-eboot -in=$(OUT_DIR)/$(PROJ_NAME).elf -out=$(OUT_DIR)/$(PROJ_NAME).oelf --paid 0x3800000000000011 +endif pre-run: @mkdir -p $(shell find '$(SRC_DIR)/' -type d -printf '$(OUT_DIR)/%p\n') @@ -97,18 +133,18 @@ $(OUT_DIR)/$(SRC_DIR)/%.o: $(SRC_DIR)/%.c ifneq ($(strip $(MIRA_CHECKS)),) @clang-tidy -checks=clang-analyzer-*,bugprone-*,portability-*,cert-* $< -- $(I_DIRS) $(C_DEFS) endif - $(CC) $(CFLAGS) -o $@ $< + @$(CC) -c $(CFLAGS) -o $@ $< $(OUT_DIR)/$(SRC_DIR)/%.o: $(SRC_DIR)/%.cpp @echo "Compiling $< ..." ifneq ($(strip $(MIRA_CHECKS)),) @clang-tidy -checks=clang-analyzer-*,bugprone-*,portability-*,cert-* $< -- $(I_DIRS) $(C_DEFS) endif - $(CPPC) $(CFLAGS) -o $@ $< + @$(CPPC) -c $(CFLAGS) -o $@ $< $(OUT_DIR)/$(SRC_DIR)/%.o: $(SRC_DIR)/%.s @echo "Assembling $< ..." - $(CC) $(SFLAGS) -o $@ $< + @$(CC) $(SFLAGS) -o $@ $< $(OUT_DIR): @mkdir $@ diff --git a/daemon/README.md b/daemon/README.md new file mode 100644 index 00000000..525ba237 --- /dev/null +++ b/daemon/README.md @@ -0,0 +1,72 @@ +# Mira daemon + +The Mira daemon is responsible for most utility usages. The daemon is where the RPC will be held, as well as the debugger, trainer scanner, and various other general purpose items. This is where Mira plugins will be loaded into, as well as having crash recovery if something goes wrong. That way you are never left without a daemon running. + +## Design + +If you were familar with how Mira's `kernel` component was laid out it is very similar. We take advantage of the Open Orbis SDK, compiling with other toolchains will have varying support. In order to build the `daemon` C++11 or greater toolchain support is needed. + +--- + +### Modules + +`IModule` interface gives the layout of any kind of code that is used within the daemon. It provides common use cases for most plugins or modules such as: + +- Load +- Unload +- Suspend +- Resume +- Name +- Description + +--- + +### Plugins +Plugins will give users the ability to load and unload code in an stable manner. Plugins inherit the `IModule` interface and should be able to be unloaded and reloaded at any point. + +There are 2 kinds of Plugins, internal and external. Internal plugins are ones that are compiled directly into the daemon itself and will always be loaded. External plugins will have to be loaded by a directory of choosing. The elf will be loaded and relocated into the current daemon process space then the `IModule.OnLoad` will be called. + +#### File Manager +Manage your files. This feature is complete and accessible over RPC. + +#### Update Removal +This feature is planned. It will check the update folder and automatically remove it on startup or via RPC if requested. + +#### Usermode Debugger and Trainer Scanner +Debugging should be handled in user mode using IOCTL extensions where needed. This will allow us to keep track of a lot more state, and also use modern C++ for development. + +This feature is still in the planning phase for vNext. + +--- + +### Rpc +The daemon will support a very basic RPC protocol using `protobuf`. The format for these messages over the wire is as specified + +``` +uint64_t messageSize; +uint8_t serializedProtobufMessage[messageSize] +``` + +Follows the `kiss` principal. The maximum message size is currently set to `64 Megabytes`. + +#### Rpc Manager +The Rpc manager is responsible for deserializing and routing messages. It will read the amount of data from the wire in the wire format above, attempt to deserialize it, then check a magic to ensure that it is working correctly. + +Each message comes in wrapped in a `Mira::Rpc::RpcMessage` as a request and response. The manager will call each `Listener` which will have to filter out which kind of message it is for dispatch. + +A `Listener` is a generic interface that will handle incoming message requests. Each of the `Listener.OnMessage` handlers should implement something similar for each of their message types that they can handle. + +``` +if (p_Request->inner_message().Is()) + return OnEcho(p_Request, p_Response); +``` + +An example listener that can be used as an example is the `FileManagerListener` which handles requests and sends back responses when completed. + +--- + +### Settings + +The daemon will be responsible as well for updating the local file settings, as well as submitting the settings changes to the `kernel` component. This feature is currently under planning stage, and has not been developed as of yet. + + diff --git a/daemon/src/Daemon.cpp b/daemon/src/Daemon.cpp index fe8a4ad8..e876ad81 100644 --- a/daemon/src/Daemon.cpp +++ b/daemon/src/Daemon.cpp @@ -1,14 +1,9 @@ #include "Daemon.hpp" -#include -#include - #include -#include #include - -#include +#include using namespace Mira; @@ -21,17 +16,15 @@ std::shared_ptr Daemon::GetInstance() Daemon::Daemon() : m_Debugger(nullptr), m_FtpServer(nullptr), - m_MessageManager(nullptr), - m_RpcServer(nullptr) + m_RpcManager(nullptr) { - // Initialize the networking - sceNetInit(); + } Daemon::~Daemon() { - if (m_RpcServer) - m_RpcServer.reset(); + if (m_RpcManager) + m_RpcManager.reset(); if (m_Debugger) m_Debugger.reset(); @@ -43,8 +36,8 @@ Daemon::~Daemon() bool Daemon::OnLoad() { // Create the message manager if it isn't already - if (!m_MessageManager) - m_MessageManager = std::make_shared(); + if (!m_RpcManager) + m_RpcManager = std::make_shared(); // Create the debugger if it isn't already if (!m_Debugger) @@ -53,18 +46,7 @@ bool Daemon::OnLoad() // Load the debugger if (!m_Debugger->OnLoad()) { - fprintf(stderr, "err: could not load debugger.\n"); - return false; - } - - // Create a new rpc server instance if it hasn't already - if (!m_RpcServer) - m_RpcServer = std::make_shared(); - - // Load the rpc server instance - if (!m_RpcServer->OnLoad()) - { - fprintf(stderr, "err: could not load rpc server.\n"); + WriteLog(LL_Error, "could not load debugger."); return false; } diff --git a/daemon/src/Daemon.hpp b/daemon/src/Daemon.hpp index 77920060..afb1ad42 100644 --- a/daemon/src/Daemon.hpp +++ b/daemon/src/Daemon.hpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace Mira { @@ -25,8 +26,7 @@ namespace Mira std::shared_ptr m_FtpServer; // RPC - std::shared_ptr m_MessageManager; - std::shared_ptr m_RpcServer; + std::shared_ptr m_RpcManager; public: static std::shared_ptr GetInstance(); @@ -36,7 +36,6 @@ namespace Mira virtual bool OnLoad() override; - std::shared_ptr GetMessageManager() const { return m_MessageManager; } - std::shared_ptr GetRpcServer() const { return m_RpcServer; } + std::shared_ptr GetMessageManager() const { return m_RpcManager; } }; }; \ No newline at end of file diff --git a/daemon/src/Debugging/Debugger.hpp b/daemon/src/Debugging/Debugger.hpp index a9fbb1eb..1622caf1 100644 --- a/daemon/src/Debugging/Debugger.hpp +++ b/daemon/src/Debugging/Debugger.hpp @@ -11,6 +11,7 @@ namespace Mira { private: + public: Debugger(); virtual ~Debugger(); diff --git a/daemon/src/Debugging/Instance.hpp b/daemon/src/Debugging/Instance.hpp index 384ddff6..4ab9e938 100644 --- a/daemon/src/Debugging/Instance.hpp +++ b/daemon/src/Debugging/Instance.hpp @@ -41,7 +41,8 @@ namespace Mira R14, R15, FS, - GS + GS, + REGS_COUNT }; int32_t m_Socket; diff --git a/daemon/src/Entry.cpp b/daemon/src/Entry.cpp index 0c372cbf..b0d0608e 100644 --- a/daemon/src/Entry.cpp +++ b/daemon/src/Entry.cpp @@ -2,24 +2,62 @@ #include #include +#include +#include + +#if defined(PS4) #include +#endif + +std::thread g_LaunchThread; + +extern "C" void trainer_load() +{ + g_LaunchThread = std::thread([]() + { + WriteLog(LL_Debug, "MiraDaemon Entry Point."); + + // Create a new instance of our daemon + auto s_Daemon = Mira::Daemon::GetInstance(); + if (s_Daemon == nullptr) + { + WriteLog(LL_Error, "could not create daemon."); + return -1; + } + + // Try and load the daemon + if (!s_Daemon->OnLoad()) + { + WriteLog(LL_Error, "could not load daemon."); + return -2; + } + + for (;;) + __asm__("nop"); + }); + + g_LaunchThread.detach(); +} + // Entry point -int main(void) +int daemon_entry(void) { + WriteLog(LL_Debug, "MiraDaemon Entry Point."); + // Create a new instance of our daemon auto s_Daemon = Mira::Daemon::GetInstance(); if (s_Daemon == nullptr) { - fprintf(stderr, "err: could not create daemon.\n"); + WriteLog(LL_Error, "could not create daemon."); return -1; } // Try and load the daemon if (!s_Daemon->OnLoad()) { - printf("err: could not load daemon.\n"); + WriteLog(LL_Error, "could not load daemon."); return -2; } diff --git a/daemon/src/Entry.hpp b/daemon/src/Entry.hpp index 6550356e..75f4ac63 100644 --- a/daemon/src/Entry.hpp +++ b/daemon/src/Entry.hpp @@ -1,2 +1,13 @@ // Main entry point -int main(void); \ No newline at end of file +extern "C" int main(void); + +/* +/data/mira +|->installed_plugins.ext +|->config_plugins.ext +|->plugins/ +| |->XXXX/ +| | |->XXX.sprx +| | |->XXX.ext +| |... +*/ \ No newline at end of file diff --git a/daemon/src/External/flatbuffers/filemanager.fbs b/daemon/src/External/flatbuffers/filemanager.fbs deleted file mode 100644 index af77323a..00000000 --- a/daemon/src/External/flatbuffers/filemanager.fbs +++ /dev/null @@ -1,119 +0,0 @@ - -namespace Mira.Plugins.FileManager; - -table EchoRequest -{ - message:string; -} - -table OpenRequest -{ - flags:int32; - mode:int32; - path:string; -} - -table CloseRequest -{ - handle:int32; -} - -table SeekRequest -{ - handle:int32; - offset:int64; -} - -table ReadRequest -{ - handle:int32; - size:uint64; -} - -table ReadResponse -{ - data:[ubyte]; -} - -table WriteRequest -{ - handle:int32; - data:[ubyte]; -} - -table Dent -{ - fileno:uint32; - recLen:uint32; - type:uint32; - name:string; -} - -table GetDentsRequest -{ - path:string; -} - -table GetDentsResponse -{ - dents:[Dent]; -} - -struct Timespec -{ - tv_sec:int64; - tv_nsec:int32; -} - -table StatRequest -{ - handle:int32; - path:string; -} - -table StatResponse -{ - st_dev:uint32; - st_ino:uint32; - st_mode:uint32; - st_nlink:uint32; - st_uid:uint32; - st_gid:uint32; - st_rdev:uint32; - st_atim:Timespec; - st_mtim:Timespec; - st_ctim:Timespec; - st_size:int64; - st_blocks:int64; - st_blksize:uint32; - st_flags:uint32; - st_gen:uint32; - st_lspare:int32; - st_birthtim:Timespec; -} - -table MkdirRequest -{ - mode:int32; - path:string; -} - -table RmdirRequest -{ - path:string; -} - -table UnlinkRequest -{ - path:string; -} - -table DecryptSelfRequest -{ - path:string; -} - -table DecryptSelfResponse -{ - data:[ubyte]; -} \ No newline at end of file diff --git a/daemon/src/External/flatbuffers/filemanager_generated.h b/daemon/src/External/flatbuffers/filemanager_generated.h deleted file mode 100644 index cf885be1..00000000 --- a/daemon/src/External/flatbuffers/filemanager_generated.h +++ /dev/null @@ -1,1165 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - - -#ifndef FLATBUFFERS_GENERATED_FILEMANAGER_MIRA_PLUGINS_FILEMANAGER_H_ -#define FLATBUFFERS_GENERATED_FILEMANAGER_MIRA_PLUGINS_FILEMANAGER_H_ - -#include "flatbuffers/flatbuffers.h" - -namespace Mira { -namespace Plugins { -namespace FileManager { - -struct EchoRequest; - -struct OpenRequest; - -struct CloseRequest; - -struct SeekRequest; - -struct ReadRequest; - -struct ReadResponse; - -struct WriteRequest; - -struct Dent; - -struct GetDentsRequest; - -struct GetDentsResponse; - -struct Timespec; - -struct StatRequest; - -struct StatResponse; - -struct MkdirRequest; - -struct RmdirRequest; - -struct UnlinkRequest; - -struct DecryptSelfRequest; - -struct DecryptSelfResponse; - -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Timespec FLATBUFFERS_FINAL_CLASS { - private: - int64_t tv_sec_; - int32_t tv_nsec_; - int32_t padding0__; - - public: - Timespec() { - memset(this, 0, sizeof(Timespec)); - } - Timespec(int64_t _tv_sec, int32_t _tv_nsec) - : tv_sec_(flatbuffers::EndianScalar(_tv_sec)), - tv_nsec_(flatbuffers::EndianScalar(_tv_nsec)), - padding0__(0) { - (void)padding0__; - } - int64_t tv_sec() const { - return flatbuffers::EndianScalar(tv_sec_); - } - int32_t tv_nsec() const { - return flatbuffers::EndianScalar(tv_nsec_); - } -}; -FLATBUFFERS_STRUCT_END(Timespec, 16); - -struct EchoRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_MESSAGE = 4 - }; - const flatbuffers::String *message() const { - return GetPointer(VT_MESSAGE); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffset(verifier, VT_MESSAGE) && - verifier.VerifyString(message()) && - verifier.EndTable(); - } -}; - -struct EchoRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_message(flatbuffers::Offset message) { - fbb_.AddOffset(EchoRequest::VT_MESSAGE, message); - } - explicit EchoRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - EchoRequestBuilder &operator=(const EchoRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateEchoRequest( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset message = 0) { - EchoRequestBuilder builder_(_fbb); - builder_.add_message(message); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateEchoRequestDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *message = nullptr) { - auto message__ = message ? _fbb.CreateString(message) : 0; - return Mira::Plugins::FileManager::CreateEchoRequest( - _fbb, - message__); -} - -struct OpenRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_FLAGS = 4, - VT_MODE = 6, - VT_PATH = 8 - }; - int32_t flags() const { - return GetField(VT_FLAGS, 0); - } - int32_t mode() const { - return GetField(VT_MODE, 0); - } - const flatbuffers::String *path() const { - return GetPointer(VT_PATH); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_FLAGS) && - VerifyField(verifier, VT_MODE) && - VerifyOffset(verifier, VT_PATH) && - verifier.VerifyString(path()) && - verifier.EndTable(); - } -}; - -struct OpenRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_flags(int32_t flags) { - fbb_.AddElement(OpenRequest::VT_FLAGS, flags, 0); - } - void add_mode(int32_t mode) { - fbb_.AddElement(OpenRequest::VT_MODE, mode, 0); - } - void add_path(flatbuffers::Offset path) { - fbb_.AddOffset(OpenRequest::VT_PATH, path); - } - explicit OpenRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - OpenRequestBuilder &operator=(const OpenRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateOpenRequest( - flatbuffers::FlatBufferBuilder &_fbb, - int32_t flags = 0, - int32_t mode = 0, - flatbuffers::Offset path = 0) { - OpenRequestBuilder builder_(_fbb); - builder_.add_path(path); - builder_.add_mode(mode); - builder_.add_flags(flags); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateOpenRequestDirect( - flatbuffers::FlatBufferBuilder &_fbb, - int32_t flags = 0, - int32_t mode = 0, - const char *path = nullptr) { - auto path__ = path ? _fbb.CreateString(path) : 0; - return Mira::Plugins::FileManager::CreateOpenRequest( - _fbb, - flags, - mode, - path__); -} - -struct CloseRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_HANDLE = 4 - }; - int32_t handle() const { - return GetField(VT_HANDLE, 0); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_HANDLE) && - verifier.EndTable(); - } -}; - -struct CloseRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_handle(int32_t handle) { - fbb_.AddElement(CloseRequest::VT_HANDLE, handle, 0); - } - explicit CloseRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - CloseRequestBuilder &operator=(const CloseRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateCloseRequest( - flatbuffers::FlatBufferBuilder &_fbb, - int32_t handle = 0) { - CloseRequestBuilder builder_(_fbb); - builder_.add_handle(handle); - return builder_.Finish(); -} - -struct SeekRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_HANDLE = 4, - VT_OFFSET = 6 - }; - int32_t handle() const { - return GetField(VT_HANDLE, 0); - } - int64_t offset() const { - return GetField(VT_OFFSET, 0); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_HANDLE) && - VerifyField(verifier, VT_OFFSET) && - verifier.EndTable(); - } -}; - -struct SeekRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_handle(int32_t handle) { - fbb_.AddElement(SeekRequest::VT_HANDLE, handle, 0); - } - void add_offset(int64_t offset) { - fbb_.AddElement(SeekRequest::VT_OFFSET, offset, 0); - } - explicit SeekRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - SeekRequestBuilder &operator=(const SeekRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateSeekRequest( - flatbuffers::FlatBufferBuilder &_fbb, - int32_t handle = 0, - int64_t offset = 0) { - SeekRequestBuilder builder_(_fbb); - builder_.add_offset(offset); - builder_.add_handle(handle); - return builder_.Finish(); -} - -struct ReadRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_HANDLE = 4, - VT_SIZE = 6 - }; - int32_t handle() const { - return GetField(VT_HANDLE, 0); - } - uint64_t size() const { - return GetField(VT_SIZE, 0); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_HANDLE) && - VerifyField(verifier, VT_SIZE) && - verifier.EndTable(); - } -}; - -struct ReadRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_handle(int32_t handle) { - fbb_.AddElement(ReadRequest::VT_HANDLE, handle, 0); - } - void add_size(uint64_t size) { - fbb_.AddElement(ReadRequest::VT_SIZE, size, 0); - } - explicit ReadRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ReadRequestBuilder &operator=(const ReadRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateReadRequest( - flatbuffers::FlatBufferBuilder &_fbb, - int32_t handle = 0, - uint64_t size = 0) { - ReadRequestBuilder builder_(_fbb); - builder_.add_size(size); - builder_.add_handle(handle); - return builder_.Finish(); -} - -struct ReadResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_DATA = 4 - }; - const flatbuffers::Vector *data() const { - return GetPointer *>(VT_DATA); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffset(verifier, VT_DATA) && - verifier.VerifyVector(data()) && - verifier.EndTable(); - } -}; - -struct ReadResponseBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_data(flatbuffers::Offset> data) { - fbb_.AddOffset(ReadResponse::VT_DATA, data); - } - explicit ReadResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ReadResponseBuilder &operator=(const ReadResponseBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateReadResponse( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset> data = 0) { - ReadResponseBuilder builder_(_fbb); - builder_.add_data(data); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateReadResponseDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const std::vector *data = nullptr) { - auto data__ = data ? _fbb.CreateVector(*data) : 0; - return Mira::Plugins::FileManager::CreateReadResponse( - _fbb, - data__); -} - -struct WriteRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_HANDLE = 4, - VT_DATA = 6 - }; - int32_t handle() const { - return GetField(VT_HANDLE, 0); - } - const flatbuffers::Vector *data() const { - return GetPointer *>(VT_DATA); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_HANDLE) && - VerifyOffset(verifier, VT_DATA) && - verifier.VerifyVector(data()) && - verifier.EndTable(); - } -}; - -struct WriteRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_handle(int32_t handle) { - fbb_.AddElement(WriteRequest::VT_HANDLE, handle, 0); - } - void add_data(flatbuffers::Offset> data) { - fbb_.AddOffset(WriteRequest::VT_DATA, data); - } - explicit WriteRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - WriteRequestBuilder &operator=(const WriteRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateWriteRequest( - flatbuffers::FlatBufferBuilder &_fbb, - int32_t handle = 0, - flatbuffers::Offset> data = 0) { - WriteRequestBuilder builder_(_fbb); - builder_.add_data(data); - builder_.add_handle(handle); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateWriteRequestDirect( - flatbuffers::FlatBufferBuilder &_fbb, - int32_t handle = 0, - const std::vector *data = nullptr) { - auto data__ = data ? _fbb.CreateVector(*data) : 0; - return Mira::Plugins::FileManager::CreateWriteRequest( - _fbb, - handle, - data__); -} - -struct Dent FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_FILENO = 4, - VT_RECLEN = 6, - VT_TYPE = 8, - VT_NAME = 10 - }; - uint32_t fileno() const { - return GetField(VT_FILENO, 0); - } - uint32_t recLen() const { - return GetField(VT_RECLEN, 0); - } - uint32_t type() const { - return GetField(VT_TYPE, 0); - } - const flatbuffers::String *name() const { - return GetPointer(VT_NAME); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_FILENO) && - VerifyField(verifier, VT_RECLEN) && - VerifyField(verifier, VT_TYPE) && - VerifyOffset(verifier, VT_NAME) && - verifier.VerifyString(name()) && - verifier.EndTable(); - } -}; - -struct DentBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_fileno(uint32_t fileno) { - fbb_.AddElement(Dent::VT_FILENO, fileno, 0); - } - void add_recLen(uint32_t recLen) { - fbb_.AddElement(Dent::VT_RECLEN, recLen, 0); - } - void add_type(uint32_t type) { - fbb_.AddElement(Dent::VT_TYPE, type, 0); - } - void add_name(flatbuffers::Offset name) { - fbb_.AddOffset(Dent::VT_NAME, name); - } - explicit DentBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - DentBuilder &operator=(const DentBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateDent( - flatbuffers::FlatBufferBuilder &_fbb, - uint32_t fileno = 0, - uint32_t recLen = 0, - uint32_t type = 0, - flatbuffers::Offset name = 0) { - DentBuilder builder_(_fbb); - builder_.add_name(name); - builder_.add_type(type); - builder_.add_recLen(recLen); - builder_.add_fileno(fileno); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateDentDirect( - flatbuffers::FlatBufferBuilder &_fbb, - uint32_t fileno = 0, - uint32_t recLen = 0, - uint32_t type = 0, - const char *name = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - return Mira::Plugins::FileManager::CreateDent( - _fbb, - fileno, - recLen, - type, - name__); -} - -struct GetDentsRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_PATH = 4 - }; - const flatbuffers::String *path() const { - return GetPointer(VT_PATH); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffset(verifier, VT_PATH) && - verifier.VerifyString(path()) && - verifier.EndTable(); - } -}; - -struct GetDentsRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_path(flatbuffers::Offset path) { - fbb_.AddOffset(GetDentsRequest::VT_PATH, path); - } - explicit GetDentsRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - GetDentsRequestBuilder &operator=(const GetDentsRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateGetDentsRequest( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset path = 0) { - GetDentsRequestBuilder builder_(_fbb); - builder_.add_path(path); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateGetDentsRequestDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *path = nullptr) { - auto path__ = path ? _fbb.CreateString(path) : 0; - return Mira::Plugins::FileManager::CreateGetDentsRequest( - _fbb, - path__); -} - -struct GetDentsResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_DENTS = 4 - }; - const flatbuffers::Vector> *dents() const { - return GetPointer> *>(VT_DENTS); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffset(verifier, VT_DENTS) && - verifier.VerifyVector(dents()) && - verifier.VerifyVectorOfTables(dents()) && - verifier.EndTable(); - } -}; - -struct GetDentsResponseBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_dents(flatbuffers::Offset>> dents) { - fbb_.AddOffset(GetDentsResponse::VT_DENTS, dents); - } - explicit GetDentsResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - GetDentsResponseBuilder &operator=(const GetDentsResponseBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateGetDentsResponse( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset>> dents = 0) { - GetDentsResponseBuilder builder_(_fbb); - builder_.add_dents(dents); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateGetDentsResponseDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const std::vector> *dents = nullptr) { - auto dents__ = dents ? _fbb.CreateVector>(*dents) : 0; - return Mira::Plugins::FileManager::CreateGetDentsResponse( - _fbb, - dents__); -} - -struct StatRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_HANDLE = 4, - VT_PATH = 6 - }; - int32_t handle() const { - return GetField(VT_HANDLE, 0); - } - const flatbuffers::String *path() const { - return GetPointer(VT_PATH); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_HANDLE) && - VerifyOffset(verifier, VT_PATH) && - verifier.VerifyString(path()) && - verifier.EndTable(); - } -}; - -struct StatRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_handle(int32_t handle) { - fbb_.AddElement(StatRequest::VT_HANDLE, handle, 0); - } - void add_path(flatbuffers::Offset path) { - fbb_.AddOffset(StatRequest::VT_PATH, path); - } - explicit StatRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - StatRequestBuilder &operator=(const StatRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateStatRequest( - flatbuffers::FlatBufferBuilder &_fbb, - int32_t handle = 0, - flatbuffers::Offset path = 0) { - StatRequestBuilder builder_(_fbb); - builder_.add_path(path); - builder_.add_handle(handle); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateStatRequestDirect( - flatbuffers::FlatBufferBuilder &_fbb, - int32_t handle = 0, - const char *path = nullptr) { - auto path__ = path ? _fbb.CreateString(path) : 0; - return Mira::Plugins::FileManager::CreateStatRequest( - _fbb, - handle, - path__); -} - -struct StatResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_ST_DEV = 4, - VT_ST_INO = 6, - VT_ST_MODE = 8, - VT_ST_NLINK = 10, - VT_ST_UID = 12, - VT_ST_GID = 14, - VT_ST_RDEV = 16, - VT_ST_ATIM = 18, - VT_ST_MTIM = 20, - VT_ST_CTIM = 22, - VT_ST_SIZE = 24, - VT_ST_BLOCKS = 26, - VT_ST_BLKSIZE = 28, - VT_ST_FLAGS = 30, - VT_ST_GEN = 32, - VT_ST_LSPARE = 34, - VT_ST_BIRTHTIM = 36 - }; - uint32_t st_dev() const { - return GetField(VT_ST_DEV, 0); - } - uint32_t st_ino() const { - return GetField(VT_ST_INO, 0); - } - uint32_t st_mode() const { - return GetField(VT_ST_MODE, 0); - } - uint32_t st_nlink() const { - return GetField(VT_ST_NLINK, 0); - } - uint32_t st_uid() const { - return GetField(VT_ST_UID, 0); - } - uint32_t st_gid() const { - return GetField(VT_ST_GID, 0); - } - uint32_t st_rdev() const { - return GetField(VT_ST_RDEV, 0); - } - const Timespec *st_atim() const { - return GetStruct(VT_ST_ATIM); - } - const Timespec *st_mtim() const { - return GetStruct(VT_ST_MTIM); - } - const Timespec *st_ctim() const { - return GetStruct(VT_ST_CTIM); - } - int64_t st_size() const { - return GetField(VT_ST_SIZE, 0); - } - int64_t st_blocks() const { - return GetField(VT_ST_BLOCKS, 0); - } - uint32_t st_blksize() const { - return GetField(VT_ST_BLKSIZE, 0); - } - uint32_t st_flags() const { - return GetField(VT_ST_FLAGS, 0); - } - uint32_t st_gen() const { - return GetField(VT_ST_GEN, 0); - } - int32_t st_lspare() const { - return GetField(VT_ST_LSPARE, 0); - } - const Timespec *st_birthtim() const { - return GetStruct(VT_ST_BIRTHTIM); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_ST_DEV) && - VerifyField(verifier, VT_ST_INO) && - VerifyField(verifier, VT_ST_MODE) && - VerifyField(verifier, VT_ST_NLINK) && - VerifyField(verifier, VT_ST_UID) && - VerifyField(verifier, VT_ST_GID) && - VerifyField(verifier, VT_ST_RDEV) && - VerifyField(verifier, VT_ST_ATIM) && - VerifyField(verifier, VT_ST_MTIM) && - VerifyField(verifier, VT_ST_CTIM) && - VerifyField(verifier, VT_ST_SIZE) && - VerifyField(verifier, VT_ST_BLOCKS) && - VerifyField(verifier, VT_ST_BLKSIZE) && - VerifyField(verifier, VT_ST_FLAGS) && - VerifyField(verifier, VT_ST_GEN) && - VerifyField(verifier, VT_ST_LSPARE) && - VerifyField(verifier, VT_ST_BIRTHTIM) && - verifier.EndTable(); - } -}; - -struct StatResponseBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_st_dev(uint32_t st_dev) { - fbb_.AddElement(StatResponse::VT_ST_DEV, st_dev, 0); - } - void add_st_ino(uint32_t st_ino) { - fbb_.AddElement(StatResponse::VT_ST_INO, st_ino, 0); - } - void add_st_mode(uint32_t st_mode) { - fbb_.AddElement(StatResponse::VT_ST_MODE, st_mode, 0); - } - void add_st_nlink(uint32_t st_nlink) { - fbb_.AddElement(StatResponse::VT_ST_NLINK, st_nlink, 0); - } - void add_st_uid(uint32_t st_uid) { - fbb_.AddElement(StatResponse::VT_ST_UID, st_uid, 0); - } - void add_st_gid(uint32_t st_gid) { - fbb_.AddElement(StatResponse::VT_ST_GID, st_gid, 0); - } - void add_st_rdev(uint32_t st_rdev) { - fbb_.AddElement(StatResponse::VT_ST_RDEV, st_rdev, 0); - } - void add_st_atim(const Timespec *st_atim) { - fbb_.AddStruct(StatResponse::VT_ST_ATIM, st_atim); - } - void add_st_mtim(const Timespec *st_mtim) { - fbb_.AddStruct(StatResponse::VT_ST_MTIM, st_mtim); - } - void add_st_ctim(const Timespec *st_ctim) { - fbb_.AddStruct(StatResponse::VT_ST_CTIM, st_ctim); - } - void add_st_size(int64_t st_size) { - fbb_.AddElement(StatResponse::VT_ST_SIZE, st_size, 0); - } - void add_st_blocks(int64_t st_blocks) { - fbb_.AddElement(StatResponse::VT_ST_BLOCKS, st_blocks, 0); - } - void add_st_blksize(uint32_t st_blksize) { - fbb_.AddElement(StatResponse::VT_ST_BLKSIZE, st_blksize, 0); - } - void add_st_flags(uint32_t st_flags) { - fbb_.AddElement(StatResponse::VT_ST_FLAGS, st_flags, 0); - } - void add_st_gen(uint32_t st_gen) { - fbb_.AddElement(StatResponse::VT_ST_GEN, st_gen, 0); - } - void add_st_lspare(int32_t st_lspare) { - fbb_.AddElement(StatResponse::VT_ST_LSPARE, st_lspare, 0); - } - void add_st_birthtim(const Timespec *st_birthtim) { - fbb_.AddStruct(StatResponse::VT_ST_BIRTHTIM, st_birthtim); - } - explicit StatResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - StatResponseBuilder &operator=(const StatResponseBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateStatResponse( - flatbuffers::FlatBufferBuilder &_fbb, - uint32_t st_dev = 0, - uint32_t st_ino = 0, - uint32_t st_mode = 0, - uint32_t st_nlink = 0, - uint32_t st_uid = 0, - uint32_t st_gid = 0, - uint32_t st_rdev = 0, - const Timespec *st_atim = 0, - const Timespec *st_mtim = 0, - const Timespec *st_ctim = 0, - int64_t st_size = 0, - int64_t st_blocks = 0, - uint32_t st_blksize = 0, - uint32_t st_flags = 0, - uint32_t st_gen = 0, - int32_t st_lspare = 0, - const Timespec *st_birthtim = 0) { - StatResponseBuilder builder_(_fbb); - builder_.add_st_blocks(st_blocks); - builder_.add_st_size(st_size); - builder_.add_st_birthtim(st_birthtim); - builder_.add_st_lspare(st_lspare); - builder_.add_st_gen(st_gen); - builder_.add_st_flags(st_flags); - builder_.add_st_blksize(st_blksize); - builder_.add_st_ctim(st_ctim); - builder_.add_st_mtim(st_mtim); - builder_.add_st_atim(st_atim); - builder_.add_st_rdev(st_rdev); - builder_.add_st_gid(st_gid); - builder_.add_st_uid(st_uid); - builder_.add_st_nlink(st_nlink); - builder_.add_st_mode(st_mode); - builder_.add_st_ino(st_ino); - builder_.add_st_dev(st_dev); - return builder_.Finish(); -} - -struct MkdirRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_MODE = 4, - VT_PATH = 6 - }; - int32_t mode() const { - return GetField(VT_MODE, 0); - } - const flatbuffers::String *path() const { - return GetPointer(VT_PATH); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_MODE) && - VerifyOffset(verifier, VT_PATH) && - verifier.VerifyString(path()) && - verifier.EndTable(); - } -}; - -struct MkdirRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_mode(int32_t mode) { - fbb_.AddElement(MkdirRequest::VT_MODE, mode, 0); - } - void add_path(flatbuffers::Offset path) { - fbb_.AddOffset(MkdirRequest::VT_PATH, path); - } - explicit MkdirRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - MkdirRequestBuilder &operator=(const MkdirRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateMkdirRequest( - flatbuffers::FlatBufferBuilder &_fbb, - int32_t mode = 0, - flatbuffers::Offset path = 0) { - MkdirRequestBuilder builder_(_fbb); - builder_.add_path(path); - builder_.add_mode(mode); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateMkdirRequestDirect( - flatbuffers::FlatBufferBuilder &_fbb, - int32_t mode = 0, - const char *path = nullptr) { - auto path__ = path ? _fbb.CreateString(path) : 0; - return Mira::Plugins::FileManager::CreateMkdirRequest( - _fbb, - mode, - path__); -} - -struct RmdirRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_PATH = 4 - }; - const flatbuffers::String *path() const { - return GetPointer(VT_PATH); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffset(verifier, VT_PATH) && - verifier.VerifyString(path()) && - verifier.EndTable(); - } -}; - -struct RmdirRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_path(flatbuffers::Offset path) { - fbb_.AddOffset(RmdirRequest::VT_PATH, path); - } - explicit RmdirRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - RmdirRequestBuilder &operator=(const RmdirRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateRmdirRequest( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset path = 0) { - RmdirRequestBuilder builder_(_fbb); - builder_.add_path(path); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateRmdirRequestDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *path = nullptr) { - auto path__ = path ? _fbb.CreateString(path) : 0; - return Mira::Plugins::FileManager::CreateRmdirRequest( - _fbb, - path__); -} - -struct UnlinkRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_PATH = 4 - }; - const flatbuffers::String *path() const { - return GetPointer(VT_PATH); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffset(verifier, VT_PATH) && - verifier.VerifyString(path()) && - verifier.EndTable(); - } -}; - -struct UnlinkRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_path(flatbuffers::Offset path) { - fbb_.AddOffset(UnlinkRequest::VT_PATH, path); - } - explicit UnlinkRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - UnlinkRequestBuilder &operator=(const UnlinkRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateUnlinkRequest( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset path = 0) { - UnlinkRequestBuilder builder_(_fbb); - builder_.add_path(path); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateUnlinkRequestDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *path = nullptr) { - auto path__ = path ? _fbb.CreateString(path) : 0; - return Mira::Plugins::FileManager::CreateUnlinkRequest( - _fbb, - path__); -} - -struct DecryptSelfRequest FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_PATH = 4 - }; - const flatbuffers::String *path() const { - return GetPointer(VT_PATH); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffset(verifier, VT_PATH) && - verifier.VerifyString(path()) && - verifier.EndTable(); - } -}; - -struct DecryptSelfRequestBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_path(flatbuffers::Offset path) { - fbb_.AddOffset(DecryptSelfRequest::VT_PATH, path); - } - explicit DecryptSelfRequestBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - DecryptSelfRequestBuilder &operator=(const DecryptSelfRequestBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateDecryptSelfRequest( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset path = 0) { - DecryptSelfRequestBuilder builder_(_fbb); - builder_.add_path(path); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateDecryptSelfRequestDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *path = nullptr) { - auto path__ = path ? _fbb.CreateString(path) : 0; - return Mira::Plugins::FileManager::CreateDecryptSelfRequest( - _fbb, - path__); -} - -struct DecryptSelfResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_DATA = 4 - }; - const flatbuffers::Vector *data() const { - return GetPointer *>(VT_DATA); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffset(verifier, VT_DATA) && - verifier.VerifyVector(data()) && - verifier.EndTable(); - } -}; - -struct DecryptSelfResponseBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_data(flatbuffers::Offset> data) { - fbb_.AddOffset(DecryptSelfResponse::VT_DATA, data); - } - explicit DecryptSelfResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - DecryptSelfResponseBuilder &operator=(const DecryptSelfResponseBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateDecryptSelfResponse( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset> data = 0) { - DecryptSelfResponseBuilder builder_(_fbb); - builder_.add_data(data); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateDecryptSelfResponseDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const std::vector *data = nullptr) { - auto data__ = data ? _fbb.CreateVector(*data) : 0; - return Mira::Plugins::FileManager::CreateDecryptSelfResponse( - _fbb, - data__); -} - -} // namespace FileManager -} // namespace Plugins -} // namespace Mira - -#endif // FLATBUFFERS_GENERATED_FILEMANAGER_MIRA_PLUGINS_FILEMANAGER_H_ diff --git a/daemon/src/External/flatbuffers/rpc.fbs b/daemon/src/External/flatbuffers/rpc.fbs deleted file mode 100644 index ed905adc..00000000 --- a/daemon/src/External/flatbuffers/rpc.fbs +++ /dev/null @@ -1,42 +0,0 @@ -// RPC IDL File - -namespace Mira.Rpc; - -enum RpcMagics : uint32 -{ - Version1 = 2, - Version2 = 0x22222222 -} - -enum RpcCategory : uint32 -{ - NONE = 0, - SYSTEM = 1, - LOG = 2, - DEBUG = 3, - FILE = 4, - COMMAND = 5, -} - -table RpcHeader -{ - // Header magic (default: 0xDEADBEEF) - magic:uint32; - - // Mira category - category:RpcCategory; - - // Message type - type:uint32; - - // User specified information (not checked by rpc) - aux:uint32; - - // Error/result - error:int64; - - // Internal message data - data:[ubyte]; -} - -root_type RpcHeader; \ No newline at end of file diff --git a/daemon/src/External/flatbuffers/rpc_generated.h b/daemon/src/External/flatbuffers/rpc_generated.h deleted file mode 100644 index c39be9e6..00000000 --- a/daemon/src/External/flatbuffers/rpc_generated.h +++ /dev/null @@ -1,222 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - - -#ifndef FLATBUFFERS_GENERATED_RPC_MIRA_RPC_H_ -#define FLATBUFFERS_GENERATED_RPC_MIRA_RPC_H_ - -#include "flatbuffers/flatbuffers.h" - -namespace Mira { -namespace Rpc { - -struct RpcHeader; - -enum RpcMagics { - RpcMagics_Version1 = 2, - RpcMagics_Version2 = 572662306, - RpcMagics_MIN = RpcMagics_Version1, - RpcMagics_MAX = RpcMagics_Version2 -}; - -inline const RpcMagics (&EnumValuesRpcMagics())[2] { - static const RpcMagics values[] = { - RpcMagics_Version1, - RpcMagics_Version2 - }; - return values; -} - -inline const char *EnumNameRpcMagics(RpcMagics e) { - switch (e) { - case RpcMagics_Version1: return "Version1"; - case RpcMagics_Version2: return "Version2"; - default: return ""; - } -} - -enum RpcCategory { - RpcCategory_NONE = 0, - RpcCategory_SYSTEM = 1, - RpcCategory_LOG = 2, - RpcCategory_DEBUG = 3, - RpcCategory_FILE = 4, - RpcCategory_COMMAND = 5, - RpcCategory_MIN = RpcCategory_NONE, - RpcCategory_MAX = RpcCategory_COMMAND -}; - -inline const RpcCategory (&EnumValuesRpcCategory())[6] { - static const RpcCategory values[] = { - RpcCategory_NONE, - RpcCategory_SYSTEM, - RpcCategory_LOG, - RpcCategory_DEBUG, - RpcCategory_FILE, - RpcCategory_COMMAND - }; - return values; -} - -inline const char * const *EnumNamesRpcCategory() { - static const char * const names[] = { - "NONE", - "SYSTEM", - "LOG", - "DEBUG", - "FILE", - "COMMAND", - nullptr - }; - return names; -} - -inline const char *EnumNameRpcCategory(RpcCategory e) { - if (e < RpcCategory_NONE || e > RpcCategory_COMMAND) return ""; - const size_t index = static_cast(e); - return EnumNamesRpcCategory()[index]; -} - -struct RpcHeader FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_MAGIC = 4, - VT_CATEGORY = 6, - VT_TYPE = 8, - VT_AUX = 10, - VT_ERROR = 12, - VT_DATA = 14 - }; - uint32_t magic() const { - return GetField(VT_MAGIC, 0); - } - RpcCategory category() const { - return static_cast(GetField(VT_CATEGORY, 0)); - } - uint32_t type() const { - return GetField(VT_TYPE, 0); - } - uint32_t aux() const { - return GetField(VT_AUX, 0); - } - int64_t error() const { - return GetField(VT_ERROR, 0); - } - const flatbuffers::Vector *data() const { - return GetPointer *>(VT_DATA); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_MAGIC) && - VerifyField(verifier, VT_CATEGORY) && - VerifyField(verifier, VT_TYPE) && - VerifyField(verifier, VT_AUX) && - VerifyField(verifier, VT_ERROR) && - VerifyOffset(verifier, VT_DATA) && - verifier.VerifyVector(data()) && - verifier.EndTable(); - } -}; - -struct RpcHeaderBuilder { - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_magic(uint32_t magic) { - fbb_.AddElement(RpcHeader::VT_MAGIC, magic, 0); - } - void add_category(RpcCategory category) { - fbb_.AddElement(RpcHeader::VT_CATEGORY, static_cast(category), 0); - } - void add_type(uint32_t type) { - fbb_.AddElement(RpcHeader::VT_TYPE, type, 0); - } - void add_aux(uint32_t aux) { - fbb_.AddElement(RpcHeader::VT_AUX, aux, 0); - } - void add_error(int64_t error) { - fbb_.AddElement(RpcHeader::VT_ERROR, error, 0); - } - void add_data(flatbuffers::Offset> data) { - fbb_.AddOffset(RpcHeader::VT_DATA, data); - } - explicit RpcHeaderBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - RpcHeaderBuilder &operator=(const RpcHeaderBuilder &); - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateRpcHeader( - flatbuffers::FlatBufferBuilder &_fbb, - uint32_t magic = 0, - RpcCategory category = RpcCategory_NONE, - uint32_t type = 0, - uint32_t aux = 0, - int64_t error = 0, - flatbuffers::Offset> data = 0) { - RpcHeaderBuilder builder_(_fbb); - builder_.add_error(error); - builder_.add_data(data); - builder_.add_aux(aux); - builder_.add_type(type); - builder_.add_category(category); - builder_.add_magic(magic); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateRpcHeaderDirect( - flatbuffers::FlatBufferBuilder &_fbb, - uint32_t magic = 0, - RpcCategory category = RpcCategory_NONE, - uint32_t type = 0, - uint32_t aux = 0, - int64_t error = 0, - const std::vector *data = nullptr) { - auto data__ = data ? _fbb.CreateVector(*data) : 0; - return Mira::Rpc::CreateRpcHeader( - _fbb, - magic, - category, - type, - aux, - error, - data__); -} - -inline const Mira::Rpc::RpcHeader *GetRpcHeader(const void *buf) { - return flatbuffers::GetRoot(buf); -} - -inline const Mira::Rpc::RpcHeader *GetSizePrefixedRpcHeader(const void *buf) { - return flatbuffers::GetSizePrefixedRoot(buf); -} - -inline bool VerifyRpcHeaderBuffer( - flatbuffers::Verifier &verifier) { - return verifier.VerifyBuffer(nullptr); -} - -inline bool VerifySizePrefixedRpcHeaderBuffer( - flatbuffers::Verifier &verifier) { - return verifier.VerifySizePrefixedBuffer(nullptr); -} - -inline void FinishRpcHeaderBuffer( - flatbuffers::FlatBufferBuilder &fbb, - flatbuffers::Offset root) { - fbb.Finish(root); -} - -inline void FinishSizePrefixedRpcHeaderBuffer( - flatbuffers::FlatBufferBuilder &fbb, - flatbuffers::Offset root) { - fbb.FinishSizePrefixed(root); -} - -} // namespace Rpc -} // namespace Mira - -#endif // FLATBUFFERS_GENERATED_RPC_MIRA_RPC_H_ diff --git a/daemon/src/External/include/Mira/Driver.hpp b/daemon/src/External/include/Mira/Driver.hpp deleted file mode 100644 index 02326914..00000000 --- a/daemon/src/External/include/Mira/Driver.hpp +++ /dev/null @@ -1,169 +0,0 @@ -#pragma once -#include - -extern "C" -{ - #define COMM_LEN 19 + 13 - #define NAME_LEN 19 + 17 - #define _MAX_PATH 1024 - - typedef enum SceAuthenticationId_t : uint64_t - { - SceVdecProxy = 0x3800000000000003ULL, - SceVencProxy = 0x3800000000000004ULL, - Orbis_audiod = 0x3800000000000005ULL, - Coredump = 0x3800000000000006ULL, - SceSysCore = 0x3800000000000007ULL, - Orbis_setip = 0x3800000000000008ULL, - GnmCompositor = 0x3800000000000009ULL, - SceShellUI = 0x380000000000000fULL, // NPXS20001 - SceShellCore = 0x3800000000000010ULL, - NPXS20103 = 0x3800000000000011ULL, - NPXS21000 = 0x3800000000000012ULL, - // TODO: Fill in the rest - Decid = 0x3800000000010003, - } SceAuthenticationId; - - typedef enum SceCapabilities_t : uint64_t - { - Max = 0xFFFFFFFFFFFFFFFFULL, - } SceCapabilites; - - // "safe" way in order to modify kernel ucred externally - typedef struct _MiraThreadCredentials { - typedef enum class _MiraThreadCredentialsPrison : uint32_t - { - // Non-root prison - Default, - - // Switch prison to root vnode - Root, - - // Total options count - COUNT - } MiraThreadCredentialsPrison; - - typedef enum class _State : uint32_t - { - Get, - Set, - COUNT - } GSState; - - // Is this a get or set operation - GSState State; - - // Process ID to modify - int32_t ProcessId; - - // Threaad ID to modify, or -1 for (all threads in process, USE WITH CAUTION) - int32_t ThreadId; - - // Everything below is Get/Set - int32_t EffectiveUserId; - int32_t RealUserId; - int32_t SavedUserId; - int32_t NumGroups; - int32_t RealGroupId; - int32_t SavedGroupId; - MiraThreadCredentialsPrison Prison; - SceAuthenticationId SceAuthId; - SceCapabilites Capabilities[4]; - uint64_t Attributes[4]; - } MiraThreadCredentials; - - typedef enum class _MiraLoadPluginType : uint8_t - { - // Don't try and load any plugin type - None, - - // Load a new kernel plugin - Kernel, - - // Load a new userland daemon plugin - Daemon, - - // Load a new game/process trainer - Trainer, - - // Total entry count - COUNT - } MiraLoadPluginType; - - // This is the requesting structure provided to the ioctl, on return a u64 as ID is returned - typedef struct _MiraLoadPlugin - { - // The plugin type to load - MiraLoadPluginType PluginType; - - // The path on filesystem of the plugin - char PluginPath[_MAX_PATH]; - } MiraLoadPlugin; - - typedef struct _MiraUnloadPlugin - { - // The returned plugin id from the plugin manager - uint64_t PluginId; - } MiraUnloadPlugin; - - typedef enum class _MiraProcessInformationType : uint8_t - { - // Do nothing - None, - - // Get process information if you know the pid - ProcessId, - - // Get process information by name (case sensitive) - Name, - - // Get process information by kernel address - Address, - - // Total option count - COUNT - } MiraProcessInformationType; - - typedef struct _MiraProcessInformation - { - typedef struct _ThreadResult - { - int32_t ThreadId; - int32_t ErrNo; - int64_t RetVal; - char Name[sizeof(((struct thread*)0)->td_name)]; - } ThreadResult; - - // Structure size - uint32_t Size; - int32_t ProcessId; - int32_t OpPid; - int32_t DebugChild; - int32_t ExitThreads; - int32_t SigParent; - int32_t Signal; - uint32_t Code; - uint32_t Stops; - uint32_t SType; - char Name[sizeof(((struct proc*)0)->p_comm)]; - char ElfPath[sizeof(((struct proc*)0)->p_elfpath)]; - char RandomizedPath[sizeof(((struct proc*)0)->p_randomized_path)]; - ThreadResult Threads[]; - } MiraProcessInformation; - - typedef struct _MiraProcessList - { - // Structure size - uint32_t Size; - - // Pid array - int32_t Pids[]; - } MiraProcessList; - - typedef struct _MiraMountInSandbox - { - int32_t Permissions; - char Path[_MAX_PATH]; - } MiraMountInSandbox; - -}; \ No newline at end of file diff --git a/daemon/src/External/include/flatbuffers/base.h b/daemon/src/External/include/flatbuffers/base.h deleted file mode 100644 index be6fa564..00000000 --- a/daemon/src/External/include/flatbuffers/base.h +++ /dev/null @@ -1,416 +0,0 @@ -#ifndef FLATBUFFERS_BASE_H_ -#define FLATBUFFERS_BASE_H_ - -// clang-format off - -// If activate should be declared and included first. -#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \ - defined(_MSC_VER) && defined(_DEBUG) - // The _CRTDBG_MAP_ALLOC inside will replace - // calloc/free (etc) to its debug version using #define directives. - #define _CRTDBG_MAP_ALLOC - #include - #include - // Replace operator new by trace-enabled version. - #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) - #define new DEBUG_NEW -#endif - -#if !defined(FLATBUFFERS_ASSERT) -#include -#define FLATBUFFERS_ASSERT assert -#elif defined(FLATBUFFERS_ASSERT_INCLUDE) -// Include file with forward declaration -#include FLATBUFFERS_ASSERT_INCLUDE -#endif - -#ifndef ARDUINO -#include -#endif - -#include -#include -#include - -#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H) - #include -#else - #include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#if defined(__unix__) && !defined(FLATBUFFERS_LOCALE_INDEPENDENT) -#include -#endif - -#ifdef _STLPORT_VERSION - #define FLATBUFFERS_CPP98_STL -#endif -#ifndef FLATBUFFERS_CPP98_STL - #include -#endif - -#ifdef __ANDROID__ - #include -#endif - -#include "flatbuffers/stl_emulation.h" - -#if defined(__ICCARM__) -#include -#endif - -// Note the __clang__ check is needed, because clang presents itself -// as an older GNUC compiler (4.2). -// Clang 3.3 and later implement all of the ISO C++ 2011 standard. -// Clang 3.4 and later implement all of the ISO C++ 2014 standard. -// http://clang.llvm.org/cxx_status.html - -// Note the MSVC value '__cplusplus' may be incorrect: -// The '__cplusplus' predefined macro in the MSVC stuck at the value 199711L, -// indicating (erroneously!) that the compiler conformed to the C++98 Standard. -// This value should be correct starting from MSVC2017-15.7-Preview-3. -// The '__cplusplus' will be valid only if MSVC2017-15.7-P3 and the `/Zc:__cplusplus` switch is set. -// Workaround (for details see MSDN): -// Use the _MSC_VER and _MSVC_LANG definition instead of the __cplusplus for compatibility. -// The _MSVC_LANG macro reports the Standard version regardless of the '/Zc:__cplusplus' switch. - -#if defined(__GNUC__) && !defined(__clang__) - #define FLATBUFFERS_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#else - #define FLATBUFFERS_GCC 0 -#endif - -#if defined(__clang__) - #define FLATBUFFERS_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) -#else - #define FLATBUFFERS_CLANG 1 -#endif - -/// @cond FLATBUFFERS_INTERNAL -#if __cplusplus <= 199711L && \ - (!defined(_MSC_VER) || _MSC_VER < 1600) && \ - (!defined(__GNUC__) || \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400)) - #error A C++11 compatible compiler with support for the auto typing is \ - required for FlatBuffers. - #error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ -#endif - -#if !defined(__clang__) && \ - defined(__GNUC__) && \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600) - // Backwards compatibility for g++ 4.4, and 4.5 which don't have the nullptr - // and constexpr keywords. Note the __clang__ check is needed, because clang - // presents itself as an older GNUC compiler. - #ifndef nullptr_t - const class nullptr_t { - public: - template inline operator T*() const { return 0; } - private: - void operator&() const; - } nullptr = {}; - #endif - #ifndef constexpr - #define constexpr const - #endif -#endif - -// The wire format uses a little endian encoding (since that's efficient for -// the common platforms). -#if defined(__s390x__) - #define FLATBUFFERS_LITTLEENDIAN 0 -#endif // __s390x__ -#if !defined(FLATBUFFERS_LITTLEENDIAN) - #if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) - #if (defined(__BIG_ENDIAN__) || \ - (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) - #define FLATBUFFERS_LITTLEENDIAN 0 - #else - #define FLATBUFFERS_LITTLEENDIAN 1 - #endif // __BIG_ENDIAN__ - #elif defined(_MSC_VER) - #if defined(_M_PPC) - #define FLATBUFFERS_LITTLEENDIAN 0 - #else - #define FLATBUFFERS_LITTLEENDIAN 1 - #endif - #else - #error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN. - #endif -#endif // !defined(FLATBUFFERS_LITTLEENDIAN) - -#define FLATBUFFERS_VERSION_MAJOR 1 -#define FLATBUFFERS_VERSION_MINOR 12 -#define FLATBUFFERS_VERSION_REVISION 0 -#define FLATBUFFERS_STRING_EXPAND(X) #X -#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) -namespace flatbuffers { - // Returns version as string "MAJOR.MINOR.REVISION". - const char* FLATBUFFERS_VERSION(); -} - -#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \ - (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \ - defined(__clang__) - #define FLATBUFFERS_FINAL_CLASS final - #define FLATBUFFERS_OVERRIDE override - #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t -#else - #define FLATBUFFERS_FINAL_CLASS - #define FLATBUFFERS_OVERRIDE - #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE -#endif - -#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ - (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ - (defined(__cpp_constexpr) && __cpp_constexpr >= 200704) - #define FLATBUFFERS_CONSTEXPR constexpr -#else - #define FLATBUFFERS_CONSTEXPR const -#endif - -#if (defined(__cplusplus) && __cplusplus >= 201402L) || \ - (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) - #define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR -#else - #define FLATBUFFERS_CONSTEXPR_CPP14 -#endif - -#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ - (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \ - defined(__clang__) - #define FLATBUFFERS_NOEXCEPT noexcept -#else - #define FLATBUFFERS_NOEXCEPT -#endif - -// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to -// private, so be sure to put it at the end or reset access mode explicitly. -#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \ - (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \ - defined(__clang__) - #define FLATBUFFERS_DELETE_FUNC(func) func = delete; -#else - #define FLATBUFFERS_DELETE_FUNC(func) private: func; -#endif - -#ifndef FLATBUFFERS_HAS_STRING_VIEW - // Only provide flatbuffers::string_view if __has_include can be used - // to detect a header that provides an implementation - #if defined(__has_include) - // Check for std::string_view (in c++17) - #if __has_include() && (__cplusplus >= 201606 || (defined(_HAS_CXX17) && _HAS_CXX17)) - #include - namespace flatbuffers { - typedef std::string_view string_view; - } - #define FLATBUFFERS_HAS_STRING_VIEW 1 - // Check for std::experimental::string_view (in c++14, compiler-dependent) - #elif __has_include() && (__cplusplus >= 201411) - #include - namespace flatbuffers { - typedef std::experimental::string_view string_view; - } - #define FLATBUFFERS_HAS_STRING_VIEW 1 - // Check for absl::string_view - #elif __has_include("absl/strings/string_view.h") - #include "absl/strings/string_view.h" - namespace flatbuffers { - typedef absl::string_view string_view; - } - #define FLATBUFFERS_HAS_STRING_VIEW 1 - #endif - #endif // __has_include -#endif // !FLATBUFFERS_HAS_STRING_VIEW - -#ifndef FLATBUFFERS_HAS_NEW_STRTOD - // Modern (C++11) strtod and strtof functions are available for use. - // 1) nan/inf strings as argument of strtod; - // 2) hex-float as argument of strtod/strtof. - #if (defined(_MSC_VER) && _MSC_VER >= 1900) || \ - (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \ - (defined(__clang__)) - #define FLATBUFFERS_HAS_NEW_STRTOD 1 - #endif -#endif // !FLATBUFFERS_HAS_NEW_STRTOD - -#ifndef FLATBUFFERS_LOCALE_INDEPENDENT - // Enable locale independent functions {strtof_l, strtod_l,strtoll_l, strtoull_l}. - #if ((defined(_MSC_VER) && _MSC_VER >= 1800) || \ - (defined(_XOPEN_VERSION) && (_XOPEN_VERSION>=700)) && (!defined(__ANDROID_API__) || (defined(__ANDROID_API__) && (__ANDROID_API__>=21)))) - #define FLATBUFFERS_LOCALE_INDEPENDENT 0 - #else - #define FLATBUFFERS_LOCALE_INDEPENDENT 0 - #endif -#endif // !FLATBUFFERS_LOCALE_INDEPENDENT - -// Suppress Undefined Behavior Sanitizer (recoverable only). Usage: -// - __supress_ubsan__("undefined") -// - __supress_ubsan__("signed-integer-overflow") -#if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7)) - #define __supress_ubsan__(type) __attribute__((no_sanitize(type))) -#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409) - #define __supress_ubsan__(type) __attribute__((no_sanitize_undefined)) -#else - #define __supress_ubsan__(type) -#endif - -// This is constexpr function used for checking compile-time constants. -// Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`. -template FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) { - return !!t; -} - -// Enable C++ attribute [[]] if std:c++17 or higher. -#if ((__cplusplus >= 201703L) \ - || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))) - // All attributes unknown to an implementation are ignored without causing an error. - #define FLATBUFFERS_ATTRIBUTE(attr) [[attr]] - - #define FLATBUFFERS_FALLTHROUGH() [[fallthrough]] -#else - #define FLATBUFFERS_ATTRIBUTE(attr) - - #if FLATBUFFERS_CLANG >= 30800 - #define FLATBUFFERS_FALLTHROUGH() [[clang::fallthrough]] - #elif FLATBUFFERS_GCC >= 70300 - #define FLATBUFFERS_FALLTHROUGH() [[gnu::fallthrough]] - #else - #define FLATBUFFERS_FALLTHROUGH() - #endif -#endif - -/// @endcond - -/// @file -namespace flatbuffers { - -/// @cond FLATBUFFERS_INTERNAL -// Our default offset / size type, 32bit on purpose on 64bit systems. -// Also, using a consistent offset type maintains compatibility of serialized -// offset values between 32bit and 64bit systems. -typedef uint32_t uoffset_t; - -// Signed offsets for references that can go in both directions. -typedef int32_t soffset_t; - -// Offset/index used in v-tables, can be changed to uint8_t in -// format forks to save a bit of space if desired. -typedef uint16_t voffset_t; - -typedef uintmax_t largest_scalar_t; - -// In 32bits, this evaluates to 2GB - 1 -#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1) - -// We support aligning the contents of buffers up to this size. -#define FLATBUFFERS_MAX_ALIGNMENT 16 - -#if defined(_MSC_VER) - #pragma warning(disable: 4351) // C4351: new behavior: elements of array ... will be default initialized - #pragma warning(push) - #pragma warning(disable: 4127) // C4127: conditional expression is constant -#endif - -template T EndianSwap(T t) { - #if defined(_MSC_VER) - #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort - #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong - #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64 - #elif defined(__ICCARM__) - #define FLATBUFFERS_BYTESWAP16 __REV16 - #define FLATBUFFERS_BYTESWAP32 __REV - #define FLATBUFFERS_BYTESWAP64(x) \ - ((__REV(static_cast(x >> 32U))) | (static_cast(__REV(static_cast(x)))) << 32U) - #else - #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__) - // __builtin_bswap16 was missing prior to GCC 4.8. - #define FLATBUFFERS_BYTESWAP16(x) \ - static_cast(__builtin_bswap32(static_cast(x) << 16)) - #else - #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16 - #endif - #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32 - #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64 - #endif - if (sizeof(T) == 1) { // Compile-time if-then's. - return t; - } else if (sizeof(T) == 2) { - union { T t; uint16_t i; } u = { t }; - u.i = FLATBUFFERS_BYTESWAP16(u.i); - return u.t; - } else if (sizeof(T) == 4) { - union { T t; uint32_t i; } u = { t }; - u.i = FLATBUFFERS_BYTESWAP32(u.i); - return u.t; - } else if (sizeof(T) == 8) { - union { T t; uint64_t i; } u = { t }; - u.i = FLATBUFFERS_BYTESWAP64(u.i); - return u.t; - } else { - FLATBUFFERS_ASSERT(0); - return t; - } -} - -#if defined(_MSC_VER) - #pragma warning(pop) -#endif - - -template T EndianScalar(T t) { - #if FLATBUFFERS_LITTLEENDIAN - return t; - #else - return EndianSwap(t); - #endif -} - -template -// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. -__supress_ubsan__("alignment") -T ReadScalar(const void *p) { - return EndianScalar(*reinterpret_cast(p)); -} - -// See https://github.com/google/flatbuffers/issues/5950 - -#if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wstringop-overflow" -#endif - -template -// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. -__supress_ubsan__("alignment") -void WriteScalar(void *p, T t) { - *reinterpret_cast(p) = EndianScalar(t); -} - -template struct Offset; -template __supress_ubsan__("alignment") void WriteScalar(void *p, Offset t) { - *reinterpret_cast(p) = EndianScalar(t.o); -} - -#if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000) - #pragma GCC diagnostic pop -#endif - -// Computes how many bytes you'd have to pad to be able to write an -// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in -// memory). -__supress_ubsan__("unsigned-integer-overflow") -inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { - return ((~buf_size) + 1) & (scalar_size - 1); -} - -} // namespace flatbuffers -#endif // FLATBUFFERS_BASE_H_ diff --git a/daemon/src/External/include/flatbuffers/code_generators.h b/daemon/src/External/include/flatbuffers/code_generators.h deleted file mode 100644 index d64ab03c..00000000 --- a/daemon/src/External/include/flatbuffers/code_generators.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_CODE_GENERATORS_H_ -#define FLATBUFFERS_CODE_GENERATORS_H_ - -#include -#include - -#include "flatbuffers/idl.h" - -namespace flatbuffers { - -// Utility class to assist in generating code through use of text templates. -// -// Example code: -// CodeWriter code("\t"); -// code.SetValue("NAME", "Foo"); -// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }"; -// code.SetValue("NAME", "Bar"); -// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }"; -// std::cout << code.ToString() << std::endl; -// -// Output: -// void Foo() { printf("%s", "Foo"); } -// void Bar() { printf("%s", "Bar"); } -class CodeWriter { - public: - CodeWriter(std::string pad = std::string()) - : pad_(pad), cur_ident_lvl_(0), ignore_ident_(false) {} - - // Clears the current "written" code. - void Clear() { - stream_.str(""); - stream_.clear(); - } - - // Associates a key with a value. All subsequent calls to operator+=, where - // the specified key is contained in {{ and }} delimiters will be replaced by - // the given value. - void SetValue(const std::string &key, const std::string &value) { - value_map_[key] = value; - } - - std::string GetValue(const std::string &key) const { - const auto it = value_map_.find(key); - return it == value_map_.end() ? "" : it->second; - } - - // Appends the given text to the generated code as well as a newline - // character. Any text within {{ and }} delimiters is replaced by values - // previously stored in the CodeWriter by calling SetValue above. The newline - // will be suppressed if the text ends with the \\ character. - void operator+=(std::string text); - - // Returns the current contents of the CodeWriter as a std::string. - std::string ToString() const { return stream_.str(); } - - // Increase ident level for writing code - void IncrementIdentLevel() { cur_ident_lvl_++; } - // Decrease ident level for writing code - void DecrementIdentLevel() { - if (cur_ident_lvl_) cur_ident_lvl_--; - } - - void SetPadding(const std::string &padding) { pad_ = padding; } - - private: - std::map value_map_; - std::stringstream stream_; - std::string pad_; - int cur_ident_lvl_; - bool ignore_ident_; - - // Add ident padding (tab or space) based on ident level - void AppendIdent(std::stringstream &stream); -}; - -class BaseGenerator { - public: - virtual bool generate() = 0; - - static std::string NamespaceDir(const Parser &parser, const std::string &path, - const Namespace &ns); - - std::string GeneratedFileName(const std::string &path, - const std::string &file_name, - const IDLOptions &options) const; - - protected: - BaseGenerator(const Parser &parser, const std::string &path, - const std::string &file_name, std::string qualifying_start, - std::string qualifying_separator, std::string default_extension) - : parser_(parser), - path_(path), - file_name_(file_name), - qualifying_start_(qualifying_start), - qualifying_separator_(qualifying_separator), - default_extension_(default_extension) {} - virtual ~BaseGenerator() {} - - // No copy/assign. - BaseGenerator &operator=(const BaseGenerator &); - BaseGenerator(const BaseGenerator &); - - std::string NamespaceDir(const Namespace &ns) const; - - static const char *FlatBuffersGeneratedWarning(); - - static std::string FullNamespace(const char *separator, const Namespace &ns); - - static std::string LastNamespacePart(const Namespace &ns); - - // tracks the current namespace for early exit in WrapInNameSpace - // c++, java and csharp returns a different namespace from - // the following default (no early exit, always fully qualify), - // which works for js and php - virtual const Namespace *CurrentNameSpace() const { return nullptr; } - - // Ensure that a type is prefixed with its namespace even within - // its own namespace to avoid conflict between generated method - // names and similarly named classes or structs - std::string WrapInNameSpace(const Namespace *ns, - const std::string &name) const; - - std::string WrapInNameSpace(const Definition &def) const; - - std::string GetNameSpace(const Definition &def) const; - - const Parser &parser_; - const std::string &path_; - const std::string &file_name_; - const std::string qualifying_start_; - const std::string qualifying_separator_; - const std::string default_extension_; -}; - -struct CommentConfig { - const char *first_line; - const char *content_line_prefix; - const char *last_line; -}; - -extern void GenComment(const std::vector &dc, - std::string *code_ptr, const CommentConfig *config, - const char *prefix = ""); - -class FloatConstantGenerator { - public: - virtual ~FloatConstantGenerator() {} - std::string GenFloatConstant(const FieldDef &field) const; - - private: - virtual std::string Value(double v, const std::string &src) const = 0; - virtual std::string Inf(double v) const = 0; - virtual std::string NaN(double v) const = 0; - - virtual std::string Value(float v, const std::string &src) const = 0; - virtual std::string Inf(float v) const = 0; - virtual std::string NaN(float v) const = 0; - - template - std::string GenFloatConstantImpl(const FieldDef &field) const; -}; - -class SimpleFloatConstantGenerator : public FloatConstantGenerator { - public: - SimpleFloatConstantGenerator(const char *nan_number, - const char *pos_inf_number, - const char *neg_inf_number); - - private: - std::string Value(double v, - const std::string &src) const FLATBUFFERS_OVERRIDE; - std::string Inf(double v) const FLATBUFFERS_OVERRIDE; - std::string NaN(double v) const FLATBUFFERS_OVERRIDE; - - std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE; - std::string Inf(float v) const FLATBUFFERS_OVERRIDE; - std::string NaN(float v) const FLATBUFFERS_OVERRIDE; - - const std::string nan_number_; - const std::string pos_inf_number_; - const std::string neg_inf_number_; -}; - -// C++, C#, Java like generator. -class TypedFloatConstantGenerator : public FloatConstantGenerator { - public: - TypedFloatConstantGenerator(const char *double_prefix, - const char *single_prefix, const char *nan_number, - const char *pos_inf_number, - const char *neg_inf_number = ""); - - private: - std::string Value(double v, - const std::string &src) const FLATBUFFERS_OVERRIDE; - std::string Inf(double v) const FLATBUFFERS_OVERRIDE; - - std::string NaN(double v) const FLATBUFFERS_OVERRIDE; - - std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE; - std::string Inf(float v) const FLATBUFFERS_OVERRIDE; - std::string NaN(float v) const FLATBUFFERS_OVERRIDE; - - std::string MakeNaN(const std::string &prefix) const; - std::string MakeInf(bool neg, const std::string &prefix) const; - - const std::string double_prefix_; - const std::string single_prefix_; - const std::string nan_number_; - const std::string pos_inf_number_; - const std::string neg_inf_number_; -}; - -} // namespace flatbuffers - -#endif // FLATBUFFERS_CODE_GENERATORS_H_ diff --git a/daemon/src/External/include/flatbuffers/flatbuffers.h b/daemon/src/External/include/flatbuffers/flatbuffers.h deleted file mode 100644 index 84110f6a..00000000 --- a/daemon/src/External/include/flatbuffers/flatbuffers.h +++ /dev/null @@ -1,2791 +0,0 @@ -/* - * Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_H_ -#define FLATBUFFERS_H_ - -#include "flatbuffers/base.h" - -#if defined(FLATBUFFERS_NAN_DEFAULTS) -# include -#endif - -namespace flatbuffers { -// Generic 'operator==' with conditional specialisations. -// T e - new value of a scalar field. -// T def - default of scalar (is known at compile-time). -template inline bool IsTheSameAs(T e, T def) { return e == def; } - -#if defined(FLATBUFFERS_NAN_DEFAULTS) && \ - defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) -// Like `operator==(e, def)` with weak NaN if T=(float|double). -template inline bool IsFloatTheSameAs(T e, T def) { - return (e == def) || ((def != def) && (e != e)); -} -template<> inline bool IsTheSameAs(float e, float def) { - return IsFloatTheSameAs(e, def); -} -template<> inline bool IsTheSameAs(double e, double def) { - return IsFloatTheSameAs(e, def); -} -#endif - -// Check 'v' is out of closed range [low; high]. -// Workaround for GCC warning [-Werror=type-limits]: -// comparison is always true due to limited range of data type. -template -inline bool IsOutRange(const T &v, const T &low, const T &high) { - return (v < low) || (high < v); -} - -// Check 'v' is in closed range [low; high]. -template -inline bool IsInRange(const T &v, const T &low, const T &high) { - return !IsOutRange(v, low, high); -} - -// Wrapper for uoffset_t to allow safe template specialization. -// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset). -template struct Offset { - uoffset_t o; - Offset() : o(0) {} - Offset(uoffset_t _o) : o(_o) {} - Offset Union() const { return Offset(o); } - bool IsNull() const { return !o; } -}; - -inline void EndianCheck() { - int endiantest = 1; - // If this fails, see FLATBUFFERS_LITTLEENDIAN above. - FLATBUFFERS_ASSERT(*reinterpret_cast(&endiantest) == - FLATBUFFERS_LITTLEENDIAN); - (void)endiantest; -} - -template FLATBUFFERS_CONSTEXPR size_t AlignOf() { - // clang-format off - #ifdef _MSC_VER - return __alignof(T); - #else - #ifndef alignof - return __alignof__(T); - #else - return alignof(T); - #endif - #endif - // clang-format on -} - -// When we read serialized data from memory, in the case of most scalars, -// we want to just read T, but in the case of Offset, we want to actually -// perform the indirection and return a pointer. -// The template specialization below does just that. -// It is wrapped in a struct since function templates can't overload on the -// return type like this. -// The typedef is for the convenience of callers of this function -// (avoiding the need for a trailing return decltype) -template struct IndirectHelper { - typedef T return_type; - typedef T mutable_return_type; - static const size_t element_stride = sizeof(T); - static return_type Read(const uint8_t *p, uoffset_t i) { - return EndianScalar((reinterpret_cast(p))[i]); - } -}; -template struct IndirectHelper> { - typedef const T *return_type; - typedef T *mutable_return_type; - static const size_t element_stride = sizeof(uoffset_t); - static return_type Read(const uint8_t *p, uoffset_t i) { - p += i * sizeof(uoffset_t); - return reinterpret_cast(p + ReadScalar(p)); - } -}; -template struct IndirectHelper { - typedef const T *return_type; - typedef T *mutable_return_type; - static const size_t element_stride = sizeof(T); - static return_type Read(const uint8_t *p, uoffset_t i) { - return reinterpret_cast(p + i * sizeof(T)); - } -}; - -// An STL compatible iterator implementation for Vector below, effectively -// calling Get() for every element. -template struct VectorIterator { - typedef std::random_access_iterator_tag iterator_category; - typedef IT value_type; - typedef ptrdiff_t difference_type; - typedef IT *pointer; - typedef IT &reference; - - VectorIterator(const uint8_t *data, uoffset_t i) - : data_(data + IndirectHelper::element_stride * i) {} - VectorIterator(const VectorIterator &other) : data_(other.data_) {} - VectorIterator() : data_(nullptr) {} - - VectorIterator &operator=(const VectorIterator &other) { - data_ = other.data_; - return *this; - } - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - VectorIterator &operator=(VectorIterator &&other) { - data_ = other.data_; - return *this; - } - #endif // !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - - bool operator==(const VectorIterator &other) const { - return data_ == other.data_; - } - - bool operator<(const VectorIterator &other) const { - return data_ < other.data_; - } - - bool operator!=(const VectorIterator &other) const { - return data_ != other.data_; - } - - difference_type operator-(const VectorIterator &other) const { - return (data_ - other.data_) / IndirectHelper::element_stride; - } - - IT operator*() const { return IndirectHelper::Read(data_, 0); } - - IT operator->() const { return IndirectHelper::Read(data_, 0); } - - VectorIterator &operator++() { - data_ += IndirectHelper::element_stride; - return *this; - } - - VectorIterator operator++(int) { - VectorIterator temp(data_, 0); - data_ += IndirectHelper::element_stride; - return temp; - } - - VectorIterator operator+(const uoffset_t &offset) const { - return VectorIterator(data_ + offset * IndirectHelper::element_stride, - 0); - } - - VectorIterator &operator+=(const uoffset_t &offset) { - data_ += offset * IndirectHelper::element_stride; - return *this; - } - - VectorIterator &operator--() { - data_ -= IndirectHelper::element_stride; - return *this; - } - - VectorIterator operator--(int) { - VectorIterator temp(data_, 0); - data_ -= IndirectHelper::element_stride; - return temp; - } - - VectorIterator operator-(const uoffset_t &offset) const { - return VectorIterator(data_ - offset * IndirectHelper::element_stride, - 0); - } - - VectorIterator &operator-=(const uoffset_t &offset) { - data_ -= offset * IndirectHelper::element_stride; - return *this; - } - - private: - const uint8_t *data_; -}; - -template -struct VectorReverseIterator : public std::reverse_iterator { - explicit VectorReverseIterator(Iterator iter) - : std::reverse_iterator(iter) {} - - typename Iterator::value_type operator*() const { - return *(std::reverse_iterator::current); - } - - typename Iterator::value_type operator->() const { - return *(std::reverse_iterator::current); - } -}; - -struct String; - -// This is used as a helper type for accessing vectors. -// Vector::data() assumes the vector elements start after the length field. -template class Vector { - public: - typedef VectorIterator::mutable_return_type> - iterator; - typedef VectorIterator::return_type> - const_iterator; - typedef VectorReverseIterator reverse_iterator; - typedef VectorReverseIterator const_reverse_iterator; - - uoffset_t size() const { return EndianScalar(length_); } - - // Deprecated: use size(). Here for backwards compatibility. - FLATBUFFERS_ATTRIBUTE(deprecated("use size() instead")) - uoffset_t Length() const { return size(); } - - typedef typename IndirectHelper::return_type return_type; - typedef typename IndirectHelper::mutable_return_type mutable_return_type; - - return_type Get(uoffset_t i) const { - FLATBUFFERS_ASSERT(i < size()); - return IndirectHelper::Read(Data(), i); - } - - return_type operator[](uoffset_t i) const { return Get(i); } - - // If this is a Vector of enums, T will be its storage type, not the enum - // type. This function makes it convenient to retrieve value with enum - // type E. - template E GetEnum(uoffset_t i) const { - return static_cast(Get(i)); - } - - // If this a vector of unions, this does the cast for you. There's no check - // to make sure this is the right type! - template const U *GetAs(uoffset_t i) const { - return reinterpret_cast(Get(i)); - } - - // If this a vector of unions, this does the cast for you. There's no check - // to make sure this is actually a string! - const String *GetAsString(uoffset_t i) const { - return reinterpret_cast(Get(i)); - } - - const void *GetStructFromOffset(size_t o) const { - return reinterpret_cast(Data() + o); - } - - iterator begin() { return iterator(Data(), 0); } - const_iterator begin() const { return const_iterator(Data(), 0); } - - iterator end() { return iterator(Data(), size()); } - const_iterator end() const { return const_iterator(Data(), size()); } - - reverse_iterator rbegin() { return reverse_iterator(end() - 1); } - const_reverse_iterator rbegin() const { - return const_reverse_iterator(end() - 1); - } - - reverse_iterator rend() { return reverse_iterator(begin() - 1); } - const_reverse_iterator rend() const { - return const_reverse_iterator(begin() - 1); - } - - const_iterator cbegin() const { return begin(); } - - const_iterator cend() const { return end(); } - - const_reverse_iterator crbegin() const { return rbegin(); } - - const_reverse_iterator crend() const { return rend(); } - - // Change elements if you have a non-const pointer to this object. - // Scalars only. See reflection.h, and the documentation. - void Mutate(uoffset_t i, const T &val) { - FLATBUFFERS_ASSERT(i < size()); - WriteScalar(data() + i, val); - } - - // Change an element of a vector of tables (or strings). - // "val" points to the new table/string, as you can obtain from - // e.g. reflection::AddFlatBuffer(). - void MutateOffset(uoffset_t i, const uint8_t *val) { - FLATBUFFERS_ASSERT(i < size()); - static_assert(sizeof(T) == sizeof(uoffset_t), "Unrelated types"); - WriteScalar(data() + i, - static_cast(val - (Data() + i * sizeof(uoffset_t)))); - } - - // Get a mutable pointer to tables/strings inside this vector. - mutable_return_type GetMutableObject(uoffset_t i) const { - FLATBUFFERS_ASSERT(i < size()); - return const_cast(IndirectHelper::Read(Data(), i)); - } - - // The raw data in little endian format. Use with care. - const uint8_t *Data() const { - return reinterpret_cast(&length_ + 1); - } - - uint8_t *Data() { return reinterpret_cast(&length_ + 1); } - - // Similarly, but typed, much like std::vector::data - const T *data() const { return reinterpret_cast(Data()); } - T *data() { return reinterpret_cast(Data()); } - - template return_type LookupByKey(K key) const { - void *search_result = std::bsearch( - &key, Data(), size(), IndirectHelper::element_stride, KeyCompare); - - if (!search_result) { - return nullptr; // Key not found. - } - - const uint8_t *element = reinterpret_cast(search_result); - - return IndirectHelper::Read(element, 0); - } - - protected: - // This class is only used to access pre-existing data. Don't ever - // try to construct these manually. - Vector(); - - uoffset_t length_; - - private: - // This class is a pointer. Copying will therefore create an invalid object. - // Private and unimplemented copy constructor. - Vector(const Vector &); - Vector &operator=(const Vector &); - - template static int KeyCompare(const void *ap, const void *bp) { - const K *key = reinterpret_cast(ap); - const uint8_t *data = reinterpret_cast(bp); - auto table = IndirectHelper::Read(data, 0); - - // std::bsearch compares with the operands transposed, so we negate the - // result here. - return -table->KeyCompareWithValue(*key); - } -}; - -// Represent a vector much like the template above, but in this case we -// don't know what the element types are (used with reflection.h). -class VectorOfAny { - public: - uoffset_t size() const { return EndianScalar(length_); } - - const uint8_t *Data() const { - return reinterpret_cast(&length_ + 1); - } - uint8_t *Data() { return reinterpret_cast(&length_ + 1); } - - protected: - VectorOfAny(); - - uoffset_t length_; - - private: - VectorOfAny(const VectorOfAny &); - VectorOfAny &operator=(const VectorOfAny &); -}; - -#ifndef FLATBUFFERS_CPP98_STL -template -Vector> *VectorCast(Vector> *ptr) { - static_assert(std::is_base_of::value, "Unrelated types"); - return reinterpret_cast> *>(ptr); -} - -template -const Vector> *VectorCast(const Vector> *ptr) { - static_assert(std::is_base_of::value, "Unrelated types"); - return reinterpret_cast> *>(ptr); -} -#endif - -// Convenient helper function to get the length of any vector, regardless -// of whether it is null or not (the field is not set). -template static inline size_t VectorLength(const Vector *v) { - return v ? v->size() : 0; -} - -// This is used as a helper type for accessing arrays. -template class Array { - typedef - typename flatbuffers::integral_constant::value> - scalar_tag; - typedef - typename flatbuffers::conditional::type - IndirectHelperType; - - public: - typedef typename IndirectHelper::return_type return_type; - typedef VectorIterator const_iterator; - typedef VectorReverseIterator const_reverse_iterator; - - FLATBUFFERS_CONSTEXPR uint16_t size() const { return length; } - - return_type Get(uoffset_t i) const { - FLATBUFFERS_ASSERT(i < size()); - return IndirectHelper::Read(Data(), i); - } - - return_type operator[](uoffset_t i) const { return Get(i); } - - // If this is a Vector of enums, T will be its storage type, not the enum - // type. This function makes it convenient to retrieve value with enum - // type E. - template E GetEnum(uoffset_t i) const { - return static_cast(Get(i)); - } - - const_iterator begin() const { return const_iterator(Data(), 0); } - const_iterator end() const { return const_iterator(Data(), size()); } - - const_reverse_iterator rbegin() const { - return const_reverse_iterator(end()); - } - const_reverse_iterator rend() const { return const_reverse_iterator(end()); } - - const_iterator cbegin() const { return begin(); } - const_iterator cend() const { return end(); } - - const_reverse_iterator crbegin() const { return rbegin(); } - const_reverse_iterator crend() const { return rend(); } - - // Get a mutable pointer to elements inside this array. - // This method used to mutate arrays of structs followed by a @p Mutate - // operation. For primitive types use @p Mutate directly. - // @warning Assignments and reads to/from the dereferenced pointer are not - // automatically converted to the correct endianness. - typename flatbuffers::conditional::type - GetMutablePointer(uoffset_t i) const { - FLATBUFFERS_ASSERT(i < size()); - return const_cast(&data()[i]); - } - - // Change elements if you have a non-const pointer to this object. - void Mutate(uoffset_t i, const T &val) { MutateImpl(scalar_tag(), i, val); } - - // The raw data in little endian format. Use with care. - const uint8_t *Data() const { return data_; } - - uint8_t *Data() { return data_; } - - // Similarly, but typed, much like std::vector::data - const T *data() const { return reinterpret_cast(Data()); } - T *data() { return reinterpret_cast(Data()); } - - protected: - void MutateImpl(flatbuffers::integral_constant, uoffset_t i, - const T &val) { - FLATBUFFERS_ASSERT(i < size()); - WriteScalar(data() + i, val); - } - - void MutateImpl(flatbuffers::integral_constant, uoffset_t i, - const T &val) { - *(GetMutablePointer(i)) = val; - } - - // This class is only used to access pre-existing data. Don't ever - // try to construct these manually. - // 'constexpr' allows us to use 'size()' at compile time. - // @note Must not use 'FLATBUFFERS_CONSTEXPR' here, as const is not allowed on - // a constructor. -#if defined(__cpp_constexpr) - constexpr Array(); -#else - Array(); -#endif - - uint8_t data_[length * sizeof(T)]; - - private: - // This class is a pointer. Copying will therefore create an invalid object. - // Private and unimplemented copy constructor. - Array(const Array &); - Array &operator=(const Array &); -}; - -// Specialization for Array[struct] with access using Offset pointer. -// This specialization used by idl_gen_text.cpp. -template class Array, length> { - static_assert(flatbuffers::is_same::value, "unexpected type T"); - - public: - typedef const void *return_type; - - const uint8_t *Data() const { return data_; } - - // Make idl_gen_text.cpp::PrintContainer happy. - return_type operator[](uoffset_t) const { - FLATBUFFERS_ASSERT(false); - return nullptr; - } - - private: - // This class is only used to access pre-existing data. - Array(); - Array(const Array &); - Array &operator=(const Array &); - - uint8_t data_[1]; -}; - -// Lexicographically compare two strings (possibly containing nulls), and -// return true if the first is less than the second. -static inline bool StringLessThan(const char *a_data, uoffset_t a_size, - const char *b_data, uoffset_t b_size) { - const auto cmp = memcmp(a_data, b_data, (std::min)(a_size, b_size)); - return cmp == 0 ? a_size < b_size : cmp < 0; -} - -struct String : public Vector { - const char *c_str() const { return reinterpret_cast(Data()); } - std::string str() const { return std::string(c_str(), size()); } - - // clang-format off - #ifdef FLATBUFFERS_HAS_STRING_VIEW - flatbuffers::string_view string_view() const { - return flatbuffers::string_view(c_str(), size()); - } - #endif // FLATBUFFERS_HAS_STRING_VIEW - // clang-format on - - bool operator<(const String &o) const { - return StringLessThan(this->data(), this->size(), o.data(), o.size()); - } -}; - -// Convenience function to get std::string from a String returning an empty -// string on null pointer. -static inline std::string GetString(const String *str) { - return str ? str->str() : ""; -} - -// Convenience function to get char* from a String returning an empty string on -// null pointer. -static inline const char *GetCstring(const String *str) { - return str ? str->c_str() : ""; -} - -#ifdef FLATBUFFERS_HAS_STRING_VIEW -// Convenience function to get string_view from a String returning an empty -// string_view on null pointer. -static inline flatbuffers::string_view GetStringView(const String *str) { - return str ? str->string_view() : flatbuffers::string_view(); -} -#endif // FLATBUFFERS_HAS_STRING_VIEW - -// Allocator interface. This is flatbuffers-specific and meant only for -// `vector_downward` usage. -class Allocator { - public: - virtual ~Allocator() {} - - // Allocate `size` bytes of memory. - virtual uint8_t *allocate(size_t size) = 0; - - // Deallocate `size` bytes of memory at `p` allocated by this allocator. - virtual void deallocate(uint8_t *p, size_t size) = 0; - - // Reallocate `new_size` bytes of memory, replacing the old region of size - // `old_size` at `p`. In contrast to a normal realloc, this grows downwards, - // and is intended specifcally for `vector_downward` use. - // `in_use_back` and `in_use_front` indicate how much of `old_size` is - // actually in use at each end, and needs to be copied. - virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size, - size_t new_size, size_t in_use_back, - size_t in_use_front) { - FLATBUFFERS_ASSERT(new_size > old_size); // vector_downward only grows - uint8_t *new_p = allocate(new_size); - memcpy_downward(old_p, old_size, new_p, new_size, in_use_back, - in_use_front); - deallocate(old_p, old_size); - return new_p; - } - - protected: - // Called by `reallocate_downward` to copy memory from `old_p` of `old_size` - // to `new_p` of `new_size`. Only memory of size `in_use_front` and - // `in_use_back` will be copied from the front and back of the old memory - // allocation. - void memcpy_downward(uint8_t *old_p, size_t old_size, uint8_t *new_p, - size_t new_size, size_t in_use_back, - size_t in_use_front) { - memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back, - in_use_back); - memcpy(new_p, old_p, in_use_front); - } -}; - -// DefaultAllocator uses new/delete to allocate memory regions -class DefaultAllocator : public Allocator { - public: - uint8_t *allocate(size_t size) FLATBUFFERS_OVERRIDE { - return new uint8_t[size]; - } - - void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; } - - static void dealloc(void *p, size_t) { delete[] static_cast(p); } -}; - -// These functions allow for a null allocator to mean use the default allocator, -// as used by DetachedBuffer and vector_downward below. -// This is to avoid having a statically or dynamically allocated default -// allocator, or having to move it between the classes that may own it. -inline uint8_t *Allocate(Allocator *allocator, size_t size) { - return allocator ? allocator->allocate(size) - : DefaultAllocator().allocate(size); -} - -inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) { - if (allocator) - allocator->deallocate(p, size); - else - DefaultAllocator().deallocate(p, size); -} - -inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p, - size_t old_size, size_t new_size, - size_t in_use_back, size_t in_use_front) { - return allocator ? allocator->reallocate_downward(old_p, old_size, new_size, - in_use_back, in_use_front) - : DefaultAllocator().reallocate_downward( - old_p, old_size, new_size, in_use_back, in_use_front); -} - -// DetachedBuffer is a finished flatbuffer memory region, detached from its -// builder. The original memory region and allocator are also stored so that -// the DetachedBuffer can manage the memory lifetime. -class DetachedBuffer { - public: - DetachedBuffer() - : allocator_(nullptr), - own_allocator_(false), - buf_(nullptr), - reserved_(0), - cur_(nullptr), - size_(0) {} - - DetachedBuffer(Allocator *allocator, bool own_allocator, uint8_t *buf, - size_t reserved, uint8_t *cur, size_t sz) - : allocator_(allocator), - own_allocator_(own_allocator), - buf_(buf), - reserved_(reserved), - cur_(cur), - size_(sz) {} - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - DetachedBuffer(DetachedBuffer &&other) - : allocator_(other.allocator_), - own_allocator_(other.own_allocator_), - buf_(other.buf_), - reserved_(other.reserved_), - cur_(other.cur_), - size_(other.size_) { - other.reset(); - } - // clang-format off - #endif // !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - DetachedBuffer &operator=(DetachedBuffer &&other) { - if (this == &other) return *this; - - destroy(); - - allocator_ = other.allocator_; - own_allocator_ = other.own_allocator_; - buf_ = other.buf_; - reserved_ = other.reserved_; - cur_ = other.cur_; - size_ = other.size_; - - other.reset(); - - return *this; - } - // clang-format off - #endif // !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - - ~DetachedBuffer() { destroy(); } - - const uint8_t *data() const { return cur_; } - - uint8_t *data() { return cur_; } - - size_t size() const { return size_; } - - // clang-format off - #if 0 // disabled for now due to the ordering of classes in this header - template - bool Verify() const { - Verifier verifier(data(), size()); - return verifier.Verify(nullptr); - } - - template - const T* GetRoot() const { - return flatbuffers::GetRoot(data()); - } - - template - T* GetRoot() { - return flatbuffers::GetRoot(data()); - } - #endif - // clang-format on - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - // These may change access mode, leave these at end of public section - FLATBUFFERS_DELETE_FUNC(DetachedBuffer(const DetachedBuffer &other)) - FLATBUFFERS_DELETE_FUNC( - DetachedBuffer &operator=(const DetachedBuffer &other)) - // clang-format off - #endif // !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - - protected: - Allocator *allocator_; - bool own_allocator_; - uint8_t *buf_; - size_t reserved_; - uint8_t *cur_; - size_t size_; - - inline void destroy() { - if (buf_) Deallocate(allocator_, buf_, reserved_); - if (own_allocator_ && allocator_) { delete allocator_; } - reset(); - } - - inline void reset() { - allocator_ = nullptr; - own_allocator_ = false; - buf_ = nullptr; - reserved_ = 0; - cur_ = nullptr; - size_ = 0; - } -}; - -// This is a minimal replication of std::vector functionality, -// except growing from higher to lower addresses. i.e push_back() inserts data -// in the lowest address in the vector. -// Since this vector leaves the lower part unused, we support a "scratch-pad" -// that can be stored there for temporary data, to share the allocated space. -// Essentially, this supports 2 std::vectors in a single buffer. -class vector_downward { - public: - explicit vector_downward(size_t initial_size, Allocator *allocator, - bool own_allocator, size_t buffer_minalign) - : allocator_(allocator), - own_allocator_(own_allocator), - initial_size_(initial_size), - buffer_minalign_(buffer_minalign), - reserved_(0), - buf_(nullptr), - cur_(nullptr), - scratch_(nullptr) {} - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - vector_downward(vector_downward &&other) - #else - vector_downward(vector_downward &other) - #endif // defined(FLATBUFFERS_CPP98_STL) - // clang-format on - : allocator_(other.allocator_), - own_allocator_(other.own_allocator_), - initial_size_(other.initial_size_), - buffer_minalign_(other.buffer_minalign_), - reserved_(other.reserved_), - buf_(other.buf_), - cur_(other.cur_), - scratch_(other.scratch_) { - // No change in other.allocator_ - // No change in other.initial_size_ - // No change in other.buffer_minalign_ - other.own_allocator_ = false; - other.reserved_ = 0; - other.buf_ = nullptr; - other.cur_ = nullptr; - other.scratch_ = nullptr; - } - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - vector_downward &operator=(vector_downward &&other) { - // Move construct a temporary and swap idiom - vector_downward temp(std::move(other)); - swap(temp); - return *this; - } - // clang-format off - #endif // defined(FLATBUFFERS_CPP98_STL) - // clang-format on - - ~vector_downward() { - clear_buffer(); - clear_allocator(); - } - - void reset() { - clear_buffer(); - clear(); - } - - void clear() { - if (buf_) { - cur_ = buf_ + reserved_; - } else { - reserved_ = 0; - cur_ = nullptr; - } - clear_scratch(); - } - - void clear_scratch() { scratch_ = buf_; } - - void clear_allocator() { - if (own_allocator_ && allocator_) { delete allocator_; } - allocator_ = nullptr; - own_allocator_ = false; - } - - void clear_buffer() { - if (buf_) Deallocate(allocator_, buf_, reserved_); - buf_ = nullptr; - } - - // Relinquish the pointer to the caller. - uint8_t *release_raw(size_t &allocated_bytes, size_t &offset) { - auto *buf = buf_; - allocated_bytes = reserved_; - offset = static_cast(cur_ - buf_); - - // release_raw only relinquishes the buffer ownership. - // Does not deallocate or reset the allocator. Destructor will do that. - buf_ = nullptr; - clear(); - return buf; - } - - // Relinquish the pointer to the caller. - DetachedBuffer release() { - // allocator ownership (if any) is transferred to DetachedBuffer. - DetachedBuffer fb(allocator_, own_allocator_, buf_, reserved_, cur_, - size()); - if (own_allocator_) { - allocator_ = nullptr; - own_allocator_ = false; - } - buf_ = nullptr; - clear(); - return fb; - } - - size_t ensure_space(size_t len) { - FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_); - if (len > static_cast(cur_ - scratch_)) { reallocate(len); } - // Beyond this, signed offsets may not have enough range: - // (FlatBuffers > 2GB not supported). - FLATBUFFERS_ASSERT(size() < FLATBUFFERS_MAX_BUFFER_SIZE); - return len; - } - - inline uint8_t *make_space(size_t len) { - size_t space = ensure_space(len); - cur_ -= space; - return cur_; - } - - // Returns nullptr if using the DefaultAllocator. - Allocator *get_custom_allocator() { return allocator_; } - - uoffset_t size() const { - return static_cast(reserved_ - (cur_ - buf_)); - } - - uoffset_t scratch_size() const { - return static_cast(scratch_ - buf_); - } - - size_t capacity() const { return reserved_; } - - uint8_t *data() const { - FLATBUFFERS_ASSERT(cur_); - return cur_; - } - - uint8_t *scratch_data() const { - FLATBUFFERS_ASSERT(buf_); - return buf_; - } - - uint8_t *scratch_end() const { - FLATBUFFERS_ASSERT(scratch_); - return scratch_; - } - - uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; } - - void push(const uint8_t *bytes, size_t num) { - if (num > 0) { memcpy(make_space(num), bytes, num); } - } - - // Specialized version of push() that avoids memcpy call for small data. - template void push_small(const T &little_endian_t) { - make_space(sizeof(T)); - *reinterpret_cast(cur_) = little_endian_t; - } - - template void scratch_push_small(const T &t) { - ensure_space(sizeof(T)); - *reinterpret_cast(scratch_) = t; - scratch_ += sizeof(T); - } - - // fill() is most frequently called with small byte counts (<= 4), - // which is why we're using loops rather than calling memset. - void fill(size_t zero_pad_bytes) { - make_space(zero_pad_bytes); - for (size_t i = 0; i < zero_pad_bytes; i++) cur_[i] = 0; - } - - // Version for when we know the size is larger. - // Precondition: zero_pad_bytes > 0 - void fill_big(size_t zero_pad_bytes) { - memset(make_space(zero_pad_bytes), 0, zero_pad_bytes); - } - - void pop(size_t bytes_to_remove) { cur_ += bytes_to_remove; } - void scratch_pop(size_t bytes_to_remove) { scratch_ -= bytes_to_remove; } - - void swap(vector_downward &other) { - using std::swap; - swap(allocator_, other.allocator_); - swap(own_allocator_, other.own_allocator_); - swap(initial_size_, other.initial_size_); - swap(buffer_minalign_, other.buffer_minalign_); - swap(reserved_, other.reserved_); - swap(buf_, other.buf_); - swap(cur_, other.cur_); - swap(scratch_, other.scratch_); - } - - void swap_allocator(vector_downward &other) { - using std::swap; - swap(allocator_, other.allocator_); - swap(own_allocator_, other.own_allocator_); - } - - private: - // You shouldn't really be copying instances of this class. - FLATBUFFERS_DELETE_FUNC(vector_downward(const vector_downward &)) - FLATBUFFERS_DELETE_FUNC(vector_downward &operator=(const vector_downward &)) - - Allocator *allocator_; - bool own_allocator_; - size_t initial_size_; - size_t buffer_minalign_; - size_t reserved_; - uint8_t *buf_; - uint8_t *cur_; // Points at location between empty (below) and used (above). - uint8_t *scratch_; // Points to the end of the scratchpad in use. - - void reallocate(size_t len) { - auto old_reserved = reserved_; - auto old_size = size(); - auto old_scratch_size = scratch_size(); - reserved_ += - (std::max)(len, old_reserved ? old_reserved / 2 : initial_size_); - reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1); - if (buf_) { - buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_, - old_size, old_scratch_size); - } else { - buf_ = Allocate(allocator_, reserved_); - } - cur_ = buf_ + reserved_ - old_size; - scratch_ = buf_ + old_scratch_size; - } -}; - -// Converts a Field ID to a virtual table offset. -inline voffset_t FieldIndexToOffset(voffset_t field_id) { - // Should correspond to what EndTable() below builds up. - const int fixed_fields = 2; // Vtable size and Object Size. - return static_cast((field_id + fixed_fields) * sizeof(voffset_t)); -} - -template -const T *data(const std::vector &v) { - // Eventually the returned pointer gets passed down to memcpy, so - // we need it to be non-null to avoid undefined behavior. - static uint8_t t; - return v.empty() ? reinterpret_cast(&t) : &v.front(); -} -template T *data(std::vector &v) { - // Eventually the returned pointer gets passed down to memcpy, so - // we need it to be non-null to avoid undefined behavior. - static uint8_t t; - return v.empty() ? reinterpret_cast(&t) : &v.front(); -} - -/// @endcond - -/// @addtogroup flatbuffers_cpp_api -/// @{ -/// @class FlatBufferBuilder -/// @brief Helper class to hold data needed in creation of a FlatBuffer. -/// To serialize data, you typically call one of the `Create*()` functions in -/// the generated code, which in turn call a sequence of `StartTable`/ -/// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/ -/// `CreateVector` functions. Do this is depth-first order to build up a tree to -/// the root. `Finish()` wraps up the buffer ready for transport. -class FlatBufferBuilder { - public: - /// @brief Default constructor for FlatBufferBuilder. - /// @param[in] initial_size The initial size of the buffer, in bytes. Defaults - /// to `1024`. - /// @param[in] allocator An `Allocator` to use. If null will use - /// `DefaultAllocator`. - /// @param[in] own_allocator Whether the builder/vector should own the - /// allocator. Defaults to / `false`. - /// @param[in] buffer_minalign Force the buffer to be aligned to the given - /// minimum alignment upon reallocation. Only needed if you intend to store - /// types with custom alignment AND you wish to read the buffer in-place - /// directly after creation. - explicit FlatBufferBuilder( - size_t initial_size = 1024, Allocator *allocator = nullptr, - bool own_allocator = false, - size_t buffer_minalign = AlignOf()) - : buf_(initial_size, allocator, own_allocator, buffer_minalign), - num_field_loc(0), - max_voffset_(0), - nested(false), - finished(false), - minalign_(1), - force_defaults_(false), - dedup_vtables_(true), - string_pool(nullptr) { - EndianCheck(); - } - - // clang-format off - /// @brief Move constructor for FlatBufferBuilder. - #if !defined(FLATBUFFERS_CPP98_STL) - FlatBufferBuilder(FlatBufferBuilder &&other) - #else - FlatBufferBuilder(FlatBufferBuilder &other) - #endif // #if !defined(FLATBUFFERS_CPP98_STL) - : buf_(1024, nullptr, false, AlignOf()), - num_field_loc(0), - max_voffset_(0), - nested(false), - finished(false), - minalign_(1), - force_defaults_(false), - dedup_vtables_(true), - string_pool(nullptr) { - EndianCheck(); - // Default construct and swap idiom. - // Lack of delegating constructors in vs2010 makes it more verbose than needed. - Swap(other); - } - // clang-format on - - // clang-format off - #if !defined(FLATBUFFERS_CPP98_STL) - // clang-format on - /// @brief Move assignment operator for FlatBufferBuilder. - FlatBufferBuilder &operator=(FlatBufferBuilder &&other) { - // Move construct a temporary and swap idiom - FlatBufferBuilder temp(std::move(other)); - Swap(temp); - return *this; - } - // clang-format off - #endif // defined(FLATBUFFERS_CPP98_STL) - // clang-format on - - void Swap(FlatBufferBuilder &other) { - using std::swap; - buf_.swap(other.buf_); - swap(num_field_loc, other.num_field_loc); - swap(max_voffset_, other.max_voffset_); - swap(nested, other.nested); - swap(finished, other.finished); - swap(minalign_, other.minalign_); - swap(force_defaults_, other.force_defaults_); - swap(dedup_vtables_, other.dedup_vtables_); - swap(string_pool, other.string_pool); - } - - ~FlatBufferBuilder() { - if (string_pool) delete string_pool; - } - - void Reset() { - Clear(); // clear builder state - buf_.reset(); // deallocate buffer - } - - /// @brief Reset all the state in this FlatBufferBuilder so it can be reused - /// to construct another buffer. - void Clear() { - ClearOffsets(); - buf_.clear(); - nested = false; - finished = false; - minalign_ = 1; - if (string_pool) string_pool->clear(); - } - - /// @brief The current size of the serialized buffer, counting from the end. - /// @return Returns an `uoffset_t` with the current size of the buffer. - uoffset_t GetSize() const { return buf_.size(); } - - /// @brief Get the serialized buffer (after you call `Finish()`). - /// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the - /// buffer. - uint8_t *GetBufferPointer() const { - Finished(); - return buf_.data(); - } - - /// @brief Get a pointer to an unfinished buffer. - /// @return Returns a `uint8_t` pointer to the unfinished buffer. - uint8_t *GetCurrentBufferPointer() const { return buf_.data(); } - - /// @brief Get the released pointer to the serialized buffer. - /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards! - /// @return A `FlatBuffer` that owns the buffer and its allocator and - /// behaves similar to a `unique_ptr` with a deleter. - FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) - DetachedBuffer ReleaseBufferPointer() { - Finished(); - return buf_.release(); - } - - /// @brief Get the released DetachedBuffer. - /// @return A `DetachedBuffer` that owns the buffer and its allocator. - DetachedBuffer Release() { - Finished(); - return buf_.release(); - } - - /// @brief Get the released pointer to the serialized buffer. - /// @param size The size of the memory block containing - /// the serialized `FlatBuffer`. - /// @param offset The offset from the released pointer where the finished - /// `FlatBuffer` starts. - /// @return A raw pointer to the start of the memory block containing - /// the serialized `FlatBuffer`. - /// @remark If the allocator is owned, it gets deleted when the destructor is - /// called.. - uint8_t *ReleaseRaw(size_t &size, size_t &offset) { - Finished(); - return buf_.release_raw(size, offset); - } - - /// @brief get the minimum alignment this buffer needs to be accessed - /// properly. This is only known once all elements have been written (after - /// you call Finish()). You can use this information if you need to embed - /// a FlatBuffer in some other buffer, such that you can later read it - /// without first having to copy it into its own buffer. - size_t GetBufferMinAlignment() const { - Finished(); - return minalign_; - } - - /// @cond FLATBUFFERS_INTERNAL - void Finished() const { - // If you get this assert, you're attempting to get access a buffer - // which hasn't been finished yet. Be sure to call - // FlatBufferBuilder::Finish with your root table. - // If you really need to access an unfinished buffer, call - // GetCurrentBufferPointer instead. - FLATBUFFERS_ASSERT(finished); - } - /// @endcond - - /// @brief In order to save space, fields that are set to their default value - /// don't get serialized into the buffer. - /// @param[in] fd When set to `true`, always serializes default values that - /// are set. Optional fields which are not set explicitly, will still not be - /// serialized. - void ForceDefaults(bool fd) { force_defaults_ = fd; } - - /// @brief By default vtables are deduped in order to save space. - /// @param[in] dedup When set to `true`, dedup vtables. - void DedupVtables(bool dedup) { dedup_vtables_ = dedup; } - - /// @cond FLATBUFFERS_INTERNAL - void Pad(size_t num_bytes) { buf_.fill(num_bytes); } - - void TrackMinAlign(size_t elem_size) { - if (elem_size > minalign_) minalign_ = elem_size; - } - - void Align(size_t elem_size) { - TrackMinAlign(elem_size); - buf_.fill(PaddingBytes(buf_.size(), elem_size)); - } - - void PushFlatBuffer(const uint8_t *bytes, size_t size) { - PushBytes(bytes, size); - finished = true; - } - - void PushBytes(const uint8_t *bytes, size_t size) { buf_.push(bytes, size); } - - void PopBytes(size_t amount) { buf_.pop(amount); } - - template void AssertScalarT() { - // The code assumes power of 2 sizes and endian-swap-ability. - static_assert(flatbuffers::is_scalar::value, "T must be a scalar type"); - } - - // Write a single aligned scalar to the buffer - template uoffset_t PushElement(T element) { - AssertScalarT(); - T litle_endian_element = EndianScalar(element); - Align(sizeof(T)); - buf_.push_small(litle_endian_element); - return GetSize(); - } - - template uoffset_t PushElement(Offset off) { - // Special case for offsets: see ReferTo below. - return PushElement(ReferTo(off.o)); - } - - // When writing fields, we track where they are, so we can create correct - // vtables later. - void TrackField(voffset_t field, uoffset_t off) { - FieldLoc fl = { off, field }; - buf_.scratch_push_small(fl); - num_field_loc++; - max_voffset_ = (std::max)(max_voffset_, field); - } - - // Like PushElement, but additionally tracks the field this represents. - template void AddElement(voffset_t field, T e, T def) { - // We don't serialize values equal to the default. - if (IsTheSameAs(e, def) && !force_defaults_) return; - auto off = PushElement(e); - TrackField(field, off); - } - - template void AddOffset(voffset_t field, Offset off) { - if (off.IsNull()) return; // Don't store. - AddElement(field, ReferTo(off.o), static_cast(0)); - } - - template void AddStruct(voffset_t field, const T *structptr) { - if (!structptr) return; // Default, don't store. - Align(AlignOf()); - buf_.push_small(*structptr); - TrackField(field, GetSize()); - } - - void AddStructOffset(voffset_t field, uoffset_t off) { - TrackField(field, off); - } - - // Offsets initially are relative to the end of the buffer (downwards). - // This function converts them to be relative to the current location - // in the buffer (when stored here), pointing upwards. - uoffset_t ReferTo(uoffset_t off) { - // Align to ensure GetSize() below is correct. - Align(sizeof(uoffset_t)); - // Offset must refer to something already in buffer. - FLATBUFFERS_ASSERT(off && off <= GetSize()); - return GetSize() - off + static_cast(sizeof(uoffset_t)); - } - - void NotNested() { - // If you hit this, you're trying to construct a Table/Vector/String - // during the construction of its parent table (between the MyTableBuilder - // and table.Finish(). - // Move the creation of these sub-objects to above the MyTableBuilder to - // not get this assert. - // Ignoring this assert may appear to work in simple cases, but the reason - // it is here is that storing objects in-line may cause vtable offsets - // to not fit anymore. It also leads to vtable duplication. - FLATBUFFERS_ASSERT(!nested); - // If you hit this, fields were added outside the scope of a table. - FLATBUFFERS_ASSERT(!num_field_loc); - } - - // From generated code (or from the parser), we call StartTable/EndTable - // with a sequence of AddElement calls in between. - uoffset_t StartTable() { - NotNested(); - nested = true; - return GetSize(); - } - - // This finishes one serialized object by generating the vtable if it's a - // table, comparing it against existing vtables, and writing the - // resulting vtable offset. - uoffset_t EndTable(uoffset_t start) { - // If you get this assert, a corresponding StartTable wasn't called. - FLATBUFFERS_ASSERT(nested); - // Write the vtable offset, which is the start of any Table. - // We fill it's value later. - auto vtableoffsetloc = PushElement(0); - // Write a vtable, which consists entirely of voffset_t elements. - // It starts with the number of offsets, followed by a type id, followed - // by the offsets themselves. In reverse: - // Include space for the last offset and ensure empty tables have a - // minimum size. - max_voffset_ = - (std::max)(static_cast(max_voffset_ + sizeof(voffset_t)), - FieldIndexToOffset(0)); - buf_.fill_big(max_voffset_); - auto table_object_size = vtableoffsetloc - start; - // Vtable use 16bit offsets. - FLATBUFFERS_ASSERT(table_object_size < 0x10000); - WriteScalar(buf_.data() + sizeof(voffset_t), - static_cast(table_object_size)); - WriteScalar(buf_.data(), max_voffset_); - // Write the offsets into the table - for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc); - it < buf_.scratch_end(); it += sizeof(FieldLoc)) { - auto field_location = reinterpret_cast(it); - auto pos = static_cast(vtableoffsetloc - field_location->off); - // If this asserts, it means you've set a field twice. - FLATBUFFERS_ASSERT( - !ReadScalar(buf_.data() + field_location->id)); - WriteScalar(buf_.data() + field_location->id, pos); - } - ClearOffsets(); - auto vt1 = reinterpret_cast(buf_.data()); - auto vt1_size = ReadScalar(vt1); - auto vt_use = GetSize(); - // See if we already have generated a vtable with this exact same - // layout before. If so, make it point to the old one, remove this one. - if (dedup_vtables_) { - for (auto it = buf_.scratch_data(); it < buf_.scratch_end(); - it += sizeof(uoffset_t)) { - auto vt_offset_ptr = reinterpret_cast(it); - auto vt2 = reinterpret_cast(buf_.data_at(*vt_offset_ptr)); - auto vt2_size = ReadScalar(vt2); - if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue; - vt_use = *vt_offset_ptr; - buf_.pop(GetSize() - vtableoffsetloc); - break; - } - } - // If this is a new vtable, remember it. - if (vt_use == GetSize()) { buf_.scratch_push_small(vt_use); } - // Fill the vtable offset we created above. - // The offset points from the beginning of the object to where the - // vtable is stored. - // Offsets default direction is downward in memory for future format - // flexibility (storing all vtables at the start of the file). - WriteScalar(buf_.data_at(vtableoffsetloc), - static_cast(vt_use) - - static_cast(vtableoffsetloc)); - - nested = false; - return vtableoffsetloc; - } - - FLATBUFFERS_ATTRIBUTE(deprecated("call the version above instead")) - uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) { - return EndTable(start); - } - - // This checks a required field has been set in a given table that has - // just been constructed. - template void Required(Offset table, voffset_t field); - - uoffset_t StartStruct(size_t alignment) { - Align(alignment); - return GetSize(); - } - - uoffset_t EndStruct() { return GetSize(); } - - void ClearOffsets() { - buf_.scratch_pop(num_field_loc * sizeof(FieldLoc)); - num_field_loc = 0; - max_voffset_ = 0; - } - - // Aligns such that when "len" bytes are written, an object can be written - // after it with "alignment" without padding. - void PreAlign(size_t len, size_t alignment) { - TrackMinAlign(alignment); - buf_.fill(PaddingBytes(GetSize() + len, alignment)); - } - template void PreAlign(size_t len) { - AssertScalarT(); - PreAlign(len, sizeof(T)); - } - /// @endcond - - /// @brief Store a string in the buffer, which can contain any binary data. - /// @param[in] str A const char pointer to the data to be stored as a string. - /// @param[in] len The number of bytes that should be stored from `str`. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const char *str, size_t len) { - NotNested(); - PreAlign(len + 1); // Always 0-terminated. - buf_.fill(1); - PushBytes(reinterpret_cast(str), len); - PushElement(static_cast(len)); - return Offset(GetSize()); - } - - /// @brief Store a string in the buffer, which is null-terminated. - /// @param[in] str A const char pointer to a C-string to add to the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const char *str) { - return CreateString(str, strlen(str)); - } - - /// @brief Store a string in the buffer, which is null-terminated. - /// @param[in] str A char pointer to a C-string to add to the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(char *str) { - return CreateString(str, strlen(str)); - } - - /// @brief Store a string in the buffer, which can contain any binary data. - /// @param[in] str A const reference to a std::string to store in the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const std::string &str) { - return CreateString(str.c_str(), str.length()); - } - - // clang-format off - #ifdef FLATBUFFERS_HAS_STRING_VIEW - /// @brief Store a string in the buffer, which can contain any binary data. - /// @param[in] str A const string_view to copy in to the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(flatbuffers::string_view str) { - return CreateString(str.data(), str.size()); - } - #endif // FLATBUFFERS_HAS_STRING_VIEW - // clang-format on - - /// @brief Store a string in the buffer, which can contain any binary data. - /// @param[in] str A const pointer to a `String` struct to add to the buffer. - /// @return Returns the offset in the buffer where the string starts - Offset CreateString(const String *str) { - return str ? CreateString(str->c_str(), str->size()) : 0; - } - - /// @brief Store a string in the buffer, which can contain any binary data. - /// @param[in] str A const reference to a std::string like type with support - /// of T::c_str() and T::length() to store in the buffer. - /// @return Returns the offset in the buffer where the string starts. - template Offset CreateString(const T &str) { - return CreateString(str.c_str(), str.length()); - } - - /// @brief Store a string in the buffer, which can contain any binary data. - /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. - /// @param[in] str A const char pointer to the data to be stored as a string. - /// @param[in] len The number of bytes that should be stored from `str`. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateSharedString(const char *str, size_t len) { - if (!string_pool) - string_pool = new StringOffsetMap(StringOffsetCompare(buf_)); - auto size_before_string = buf_.size(); - // Must first serialize the string, since the set is all offsets into - // buffer. - auto off = CreateString(str, len); - auto it = string_pool->find(off); - // If it exists we reuse existing serialized data! - if (it != string_pool->end()) { - // We can remove the string we serialized. - buf_.pop(buf_.size() - size_before_string); - return *it; - } - // Record this string for future use. - string_pool->insert(off); - return off; - } - - /// @brief Store a string in the buffer, which null-terminated. - /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. - /// @param[in] str A const char pointer to a C-string to add to the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateSharedString(const char *str) { - return CreateSharedString(str, strlen(str)); - } - - /// @brief Store a string in the buffer, which can contain any binary data. - /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. - /// @param[in] str A const reference to a std::string to store in the buffer. - /// @return Returns the offset in the buffer where the string starts. - Offset CreateSharedString(const std::string &str) { - return CreateSharedString(str.c_str(), str.length()); - } - - /// @brief Store a string in the buffer, which can contain any binary data. - /// If a string with this exact contents has already been serialized before, - /// instead simply returns the offset of the existing string. - /// @param[in] str A const pointer to a `String` struct to add to the buffer. - /// @return Returns the offset in the buffer where the string starts - Offset CreateSharedString(const String *str) { - return CreateSharedString(str->c_str(), str->size()); - } - - /// @cond FLATBUFFERS_INTERNAL - uoffset_t EndVector(size_t len) { - FLATBUFFERS_ASSERT(nested); // Hit if no corresponding StartVector. - nested = false; - return PushElement(static_cast(len)); - } - - void StartVector(size_t len, size_t elemsize) { - NotNested(); - nested = true; - PreAlign(len * elemsize); - PreAlign(len * elemsize, elemsize); // Just in case elemsize > uoffset_t. - } - - // Call this right before StartVector/CreateVector if you want to force the - // alignment to be something different than what the element size would - // normally dictate. - // This is useful when storing a nested_flatbuffer in a vector of bytes, - // or when storing SIMD floats, etc. - void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) { - PreAlign(len * elemsize, alignment); - } - - // Similar to ForceVectorAlignment but for String fields. - void ForceStringAlignment(size_t len, size_t alignment) { - PreAlign((len + 1) * sizeof(char), alignment); - } - - /// @endcond - - /// @brief Serialize an array into a FlatBuffer `vector`. - /// @tparam T The data type of the array elements. - /// @param[in] v A pointer to the array of type `T` to serialize into the - /// buffer as a `vector`. - /// @param[in] len The number of elements to serialize. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template Offset> CreateVector(const T *v, size_t len) { - // If this assert hits, you're specifying a template argument that is - // causing the wrong overload to be selected, remove it. - AssertScalarT(); - StartVector(len, sizeof(T)); - // clang-format off - #if FLATBUFFERS_LITTLEENDIAN - PushBytes(reinterpret_cast(v), len * sizeof(T)); - #else - if (sizeof(T) == 1) { - PushBytes(reinterpret_cast(v), len); - } else { - for (auto i = len; i > 0; ) { - PushElement(v[--i]); - } - } - #endif - // clang-format on - return Offset>(EndVector(len)); - } - - template - Offset>> CreateVector(const Offset *v, size_t len) { - StartVector(len, sizeof(Offset)); - for (auto i = len; i > 0;) { PushElement(v[--i]); } - return Offset>>(EndVector(len)); - } - - /// @brief Serialize a `std::vector` into a FlatBuffer `vector`. - /// @tparam T The data type of the `std::vector` elements. - /// @param v A const reference to the `std::vector` to serialize into the - /// buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template Offset> CreateVector(const std::vector &v) { - return CreateVector(data(v), v.size()); - } - - // vector may be implemented using a bit-set, so we can't access it as - // an array. Instead, read elements manually. - // Background: https://isocpp.org/blog/2012/11/on-vectorbool - Offset> CreateVector(const std::vector &v) { - StartVector(v.size(), sizeof(uint8_t)); - for (auto i = v.size(); i > 0;) { - PushElement(static_cast(v[--i])); - } - return Offset>(EndVector(v.size())); - } - - // clang-format off - #ifndef FLATBUFFERS_CPP98_STL - /// @brief Serialize values returned by a function into a FlatBuffer `vector`. - /// This is a convenience function that takes care of iteration for you. - /// @tparam T The data type of the `std::vector` elements. - /// @param f A function that takes the current iteration 0..vector_size-1 and - /// returns any type that you can construct a FlatBuffers vector out of. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template Offset> CreateVector(size_t vector_size, - const std::function &f) { - std::vector elems(vector_size); - for (size_t i = 0; i < vector_size; i++) elems[i] = f(i); - return CreateVector(elems); - } - #endif - // clang-format on - - /// @brief Serialize values returned by a function into a FlatBuffer `vector`. - /// This is a convenience function that takes care of iteration for you. - /// @tparam T The data type of the `std::vector` elements. - /// @param f A function that takes the current iteration 0..vector_size-1, - /// and the state parameter returning any type that you can construct a - /// FlatBuffers vector out of. - /// @param state State passed to f. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVector(size_t vector_size, F f, S *state) { - std::vector elems(vector_size); - for (size_t i = 0; i < vector_size; i++) elems[i] = f(i, state); - return CreateVector(elems); - } - - /// @brief Serialize a `std::vector` into a FlatBuffer `vector`. - /// This is a convenience function for a common case. - /// @param v A const reference to the `std::vector` to serialize into the - /// buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - Offset>> CreateVectorOfStrings( - const std::vector &v) { - std::vector> offsets(v.size()); - for (size_t i = 0; i < v.size(); i++) offsets[i] = CreateString(v[i]); - return CreateVector(offsets); - } - - /// @brief Serialize an array of structs into a FlatBuffer `vector`. - /// @tparam T The data type of the struct array elements. - /// @param[in] v A pointer to the array of type `T` to serialize into the - /// buffer as a `vector`. - /// @param[in] len The number of elements to serialize. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfStructs(const T *v, size_t len) { - StartVector(len * sizeof(T) / AlignOf(), AlignOf()); - PushBytes(reinterpret_cast(v), sizeof(T) * len); - return Offset>(EndVector(len)); - } - - /// @brief Serialize an array of native structs into a FlatBuffer `vector`. - /// @tparam T The data type of the struct array elements. - /// @tparam S The data type of the native struct array elements. - /// @param[in] v A pointer to the array of type `S` to serialize into the - /// buffer as a `vector`. - /// @param[in] len The number of elements to serialize. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfNativeStructs(const S *v, - size_t len) { - extern T Pack(const S &); - std::vector vv(len); - std::transform(v, v + len, vv.begin(), Pack); - return CreateVectorOfStructs(data(vv), vv.size()); - } - - // clang-format off - #ifndef FLATBUFFERS_CPP98_STL - /// @brief Serialize an array of structs into a FlatBuffer `vector`. - /// @tparam T The data type of the struct array elements. - /// @param[in] filler A function that takes the current iteration 0..vector_size-1 - /// and a pointer to the struct that must be filled. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - /// This is mostly useful when flatbuffers are generated with mutation - /// accessors. - template Offset> CreateVectorOfStructs( - size_t vector_size, const std::function &filler) { - T* structs = StartVectorOfStructs(vector_size); - for (size_t i = 0; i < vector_size; i++) { - filler(i, structs); - structs++; - } - return EndVectorOfStructs(vector_size); - } - #endif - // clang-format on - - /// @brief Serialize an array of structs into a FlatBuffer `vector`. - /// @tparam T The data type of the struct array elements. - /// @param[in] f A function that takes the current iteration 0..vector_size-1, - /// a pointer to the struct that must be filled and the state argument. - /// @param[in] state Arbitrary state to pass to f. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - /// This is mostly useful when flatbuffers are generated with mutation - /// accessors. - template - Offset> CreateVectorOfStructs(size_t vector_size, F f, - S *state) { - T *structs = StartVectorOfStructs(vector_size); - for (size_t i = 0; i < vector_size; i++) { - f(i, structs, state); - structs++; - } - return EndVectorOfStructs(vector_size); - } - - /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`. - /// @tparam T The data type of the `std::vector` struct elements. - /// @param[in] v A const reference to the `std::vector` of structs to - /// serialize into the buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfStructs( - const std::vector &v) { - return CreateVectorOfStructs(data(v), v.size()); - } - - /// @brief Serialize a `std::vector` of native structs into a FlatBuffer - /// `vector`. - /// @tparam T The data type of the `std::vector` struct elements. - /// @tparam S The data type of the `std::vector` native struct elements. - /// @param[in] v A const reference to the `std::vector` of structs to - /// serialize into the buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfNativeStructs( - const std::vector &v) { - return CreateVectorOfNativeStructs(data(v), v.size()); - } - - /// @cond FLATBUFFERS_INTERNAL - template struct StructKeyComparator { - bool operator()(const T &a, const T &b) const { - return a.KeyCompareLessThan(&b); - } - - FLATBUFFERS_DELETE_FUNC( - StructKeyComparator &operator=(const StructKeyComparator &)) - }; - /// @endcond - - /// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector` - /// in sorted order. - /// @tparam T The data type of the `std::vector` struct elements. - /// @param[in] v A const reference to the `std::vector` of structs to - /// serialize into the buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfSortedStructs(std::vector *v) { - return CreateVectorOfSortedStructs(data(*v), v->size()); - } - - /// @brief Serialize a `std::vector` of native structs into a FlatBuffer - /// `vector` in sorted order. - /// @tparam T The data type of the `std::vector` struct elements. - /// @tparam S The data type of the `std::vector` native struct elements. - /// @param[in] v A const reference to the `std::vector` of structs to - /// serialize into the buffer as a `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfSortedNativeStructs( - std::vector *v) { - return CreateVectorOfSortedNativeStructs(data(*v), v->size()); - } - - /// @brief Serialize an array of structs into a FlatBuffer `vector` in sorted - /// order. - /// @tparam T The data type of the struct array elements. - /// @param[in] v A pointer to the array of type `T` to serialize into the - /// buffer as a `vector`. - /// @param[in] len The number of elements to serialize. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfSortedStructs(T *v, size_t len) { - std::sort(v, v + len, StructKeyComparator()); - return CreateVectorOfStructs(v, len); - } - - /// @brief Serialize an array of native structs into a FlatBuffer `vector` in - /// sorted order. - /// @tparam T The data type of the struct array elements. - /// @tparam S The data type of the native struct array elements. - /// @param[in] v A pointer to the array of type `S` to serialize into the - /// buffer as a `vector`. - /// @param[in] len The number of elements to serialize. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset> CreateVectorOfSortedNativeStructs(S *v, - size_t len) { - extern T Pack(const S &); - typedef T (*Pack_t)(const S &); - std::vector vv(len); - std::transform(v, v + len, vv.begin(), static_cast(Pack)); - return CreateVectorOfSortedStructs(vv, len); - } - - /// @cond FLATBUFFERS_INTERNAL - template struct TableKeyComparator { - TableKeyComparator(vector_downward &buf) : buf_(buf) {} - TableKeyComparator(const TableKeyComparator &other) : buf_(other.buf_) {} - bool operator()(const Offset &a, const Offset &b) const { - auto table_a = reinterpret_cast(buf_.data_at(a.o)); - auto table_b = reinterpret_cast(buf_.data_at(b.o)); - return table_a->KeyCompareLessThan(table_b); - } - vector_downward &buf_; - - private: - TableKeyComparator &operator=(const TableKeyComparator &other) { - buf_ = other.buf_; - return *this; - } - }; - /// @endcond - - /// @brief Serialize an array of `table` offsets as a `vector` in the buffer - /// in sorted order. - /// @tparam T The data type that the offset refers to. - /// @param[in] v An array of type `Offset` that contains the `table` - /// offsets to store in the buffer in sorted order. - /// @param[in] len The number of elements to store in the `vector`. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset>> CreateVectorOfSortedTables(Offset *v, - size_t len) { - std::sort(v, v + len, TableKeyComparator(buf_)); - return CreateVector(v, len); - } - - /// @brief Serialize an array of `table` offsets as a `vector` in the buffer - /// in sorted order. - /// @tparam T The data type that the offset refers to. - /// @param[in] v An array of type `Offset` that contains the `table` - /// offsets to store in the buffer in sorted order. - /// @return Returns a typed `Offset` into the serialized data indicating - /// where the vector is stored. - template - Offset>> CreateVectorOfSortedTables( - std::vector> *v) { - return CreateVectorOfSortedTables(data(*v), v->size()); - } - - /// @brief Specialized version of `CreateVector` for non-copying use cases. - /// Write the data any time later to the returned buffer pointer `buf`. - /// @param[in] len The number of elements to store in the `vector`. - /// @param[in] elemsize The size of each element in the `vector`. - /// @param[out] buf A pointer to a `uint8_t` pointer that can be - /// written to at a later time to serialize the data into a `vector` - /// in the buffer. - uoffset_t CreateUninitializedVector(size_t len, size_t elemsize, - uint8_t **buf) { - NotNested(); - StartVector(len, elemsize); - buf_.make_space(len * elemsize); - auto vec_start = GetSize(); - auto vec_end = EndVector(len); - *buf = buf_.data_at(vec_start); - return vec_end; - } - - /// @brief Specialized version of `CreateVector` for non-copying use cases. - /// Write the data any time later to the returned buffer pointer `buf`. - /// @tparam T The data type of the data that will be stored in the buffer - /// as a `vector`. - /// @param[in] len The number of elements to store in the `vector`. - /// @param[out] buf A pointer to a pointer of type `T` that can be - /// written to at a later time to serialize the data into a `vector` - /// in the buffer. - template - Offset> CreateUninitializedVector(size_t len, T **buf) { - AssertScalarT(); - return CreateUninitializedVector(len, sizeof(T), - reinterpret_cast(buf)); - } - - template - Offset> CreateUninitializedVectorOfStructs(size_t len, - T **buf) { - return CreateUninitializedVector(len, sizeof(T), - reinterpret_cast(buf)); - } - - // @brief Create a vector of scalar type T given as input a vector of scalar - // type U, useful with e.g. pre "enum class" enums, or any existing scalar - // data of the wrong type. - template - Offset> CreateVectorScalarCast(const U *v, size_t len) { - AssertScalarT(); - AssertScalarT(); - StartVector(len, sizeof(T)); - for (auto i = len; i > 0;) { PushElement(static_cast(v[--i])); } - return Offset>(EndVector(len)); - } - - /// @brief Write a struct by itself, typically to be part of a union. - template Offset CreateStruct(const T &structobj) { - NotNested(); - Align(AlignOf()); - buf_.push_small(structobj); - return Offset(GetSize()); - } - - /// @brief The length of a FlatBuffer file header. - static const size_t kFileIdentifierLength = 4; - - /// @brief Finish serializing a buffer by writing the root offset. - /// @param[in] file_identifier If a `file_identifier` is given, the buffer - /// will be prefixed with a standard FlatBuffers file header. - template - void Finish(Offset root, const char *file_identifier = nullptr) { - Finish(root.o, file_identifier, false); - } - - /// @brief Finish a buffer with a 32 bit size field pre-fixed (size of the - /// buffer following the size field). These buffers are NOT compatible - /// with standard buffers created by Finish, i.e. you can't call GetRoot - /// on them, you have to use GetSizePrefixedRoot instead. - /// All >32 bit quantities in this buffer will be aligned when the whole - /// size pre-fixed buffer is aligned. - /// These kinds of buffers are useful for creating a stream of FlatBuffers. - template - void FinishSizePrefixed(Offset root, - const char *file_identifier = nullptr) { - Finish(root.o, file_identifier, true); - } - - void SwapBufAllocator(FlatBufferBuilder &other) { - buf_.swap_allocator(other.buf_); - } - - protected: - // You shouldn't really be copying instances of this class. - FlatBufferBuilder(const FlatBufferBuilder &); - FlatBufferBuilder &operator=(const FlatBufferBuilder &); - - void Finish(uoffset_t root, const char *file_identifier, bool size_prefix) { - NotNested(); - buf_.clear_scratch(); - // This will cause the whole buffer to be aligned. - PreAlign((size_prefix ? sizeof(uoffset_t) : 0) + sizeof(uoffset_t) + - (file_identifier ? kFileIdentifierLength : 0), - minalign_); - if (file_identifier) { - FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength); - PushBytes(reinterpret_cast(file_identifier), - kFileIdentifierLength); - } - PushElement(ReferTo(root)); // Location of root. - if (size_prefix) { PushElement(GetSize()); } - finished = true; - } - - struct FieldLoc { - uoffset_t off; - voffset_t id; - }; - - vector_downward buf_; - - // Accumulating offsets of table members while it is being built. - // We store these in the scratch pad of buf_, after the vtable offsets. - uoffset_t num_field_loc; - // Track how much of the vtable is in use, so we can output the most compact - // possible vtable. - voffset_t max_voffset_; - - // Ensure objects are not nested. - bool nested; - - // Ensure the buffer is finished before it is being accessed. - bool finished; - - size_t minalign_; - - bool force_defaults_; // Serialize values equal to their defaults anyway. - - bool dedup_vtables_; - - struct StringOffsetCompare { - StringOffsetCompare(const vector_downward &buf) : buf_(&buf) {} - bool operator()(const Offset &a, const Offset &b) const { - auto stra = reinterpret_cast(buf_->data_at(a.o)); - auto strb = reinterpret_cast(buf_->data_at(b.o)); - return StringLessThan(stra->data(), stra->size(), strb->data(), - strb->size()); - } - const vector_downward *buf_; - }; - - // For use with CreateSharedString. Instantiated on first use only. - typedef std::set, StringOffsetCompare> StringOffsetMap; - StringOffsetMap *string_pool; - - private: - // Allocates space for a vector of structures. - // Must be completed with EndVectorOfStructs(). - template T *StartVectorOfStructs(size_t vector_size) { - StartVector(vector_size * sizeof(T) / AlignOf(), AlignOf()); - return reinterpret_cast(buf_.make_space(vector_size * sizeof(T))); - } - - // End the vector of structues in the flatbuffers. - // Vector should have previously be started with StartVectorOfStructs(). - template - Offset> EndVectorOfStructs(size_t vector_size) { - return Offset>(EndVector(vector_size)); - } -}; -/// @} - -/// @cond FLATBUFFERS_INTERNAL -// Helpers to get a typed pointer to the root object contained in the buffer. -template T *GetMutableRoot(void *buf) { - EndianCheck(); - return reinterpret_cast( - reinterpret_cast(buf) + - EndianScalar(*reinterpret_cast(buf))); -} - -template const T *GetRoot(const void *buf) { - return GetMutableRoot(const_cast(buf)); -} - -template const T *GetSizePrefixedRoot(const void *buf) { - return GetRoot(reinterpret_cast(buf) + sizeof(uoffset_t)); -} - -/// Helpers to get a typed pointer to objects that are currently being built. -/// @warning Creating new objects will lead to reallocations and invalidates -/// the pointer! -template -T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset offset) { - return reinterpret_cast(fbb.GetCurrentBufferPointer() + fbb.GetSize() - - offset.o); -} - -template -const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset offset) { - return GetMutableTemporaryPointer(fbb, offset); -} - -/// @brief Get a pointer to the the file_identifier section of the buffer. -/// @return Returns a const char pointer to the start of the file_identifier -/// characters in the buffer. The returned char * has length -/// 'flatbuffers::FlatBufferBuilder::kFileIdentifierLength'. -/// This function is UNDEFINED for FlatBuffers whose schema does not include -/// a file_identifier (likely points at padding or the start of a the root -/// vtable). -inline const char *GetBufferIdentifier(const void *buf, - bool size_prefixed = false) { - return reinterpret_cast(buf) + - ((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t)); -} - -// Helper to see if the identifier in a buffer has the expected value. -inline bool BufferHasIdentifier(const void *buf, const char *identifier, - bool size_prefixed = false) { - return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier, - FlatBufferBuilder::kFileIdentifierLength) == 0; -} - -// Helper class to verify the integrity of a FlatBuffer -class Verifier FLATBUFFERS_FINAL_CLASS { - public: - Verifier(const uint8_t *buf, size_t buf_len, uoffset_t _max_depth = 64, - uoffset_t _max_tables = 1000000, bool _check_alignment = true) - : buf_(buf), - size_(buf_len), - depth_(0), - max_depth_(_max_depth), - num_tables_(0), - max_tables_(_max_tables), - upper_bound_(0), - check_alignment_(_check_alignment) { - FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE); - } - - // Central location where any verification failures register. - bool Check(bool ok) const { - // clang-format off - #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE - FLATBUFFERS_ASSERT(ok); - #endif - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - if (!ok) - upper_bound_ = 0; - #endif - // clang-format on - return ok; - } - - // Verify any range within the buffer. - bool Verify(size_t elem, size_t elem_len) const { - // clang-format off - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - auto upper_bound = elem + elem_len; - if (upper_bound_ < upper_bound) - upper_bound_ = upper_bound; - #endif - // clang-format on - return Check(elem_len < size_ && elem <= size_ - elem_len); - } - - template bool VerifyAlignment(size_t elem) const { - return Check((elem & (sizeof(T) - 1)) == 0 || !check_alignment_); - } - - // Verify a range indicated by sizeof(T). - template bool Verify(size_t elem) const { - return VerifyAlignment(elem) && Verify(elem, sizeof(T)); - } - - bool VerifyFromPointer(const uint8_t *p, size_t len) { - auto o = static_cast(p - buf_); - return Verify(o, len); - } - - // Verify relative to a known-good base pointer. - bool Verify(const uint8_t *base, voffset_t elem_off, size_t elem_len) const { - return Verify(static_cast(base - buf_) + elem_off, elem_len); - } - - template - bool Verify(const uint8_t *base, voffset_t elem_off) const { - return Verify(static_cast(base - buf_) + elem_off, sizeof(T)); - } - - // Verify a pointer (may be NULL) of a table type. - template bool VerifyTable(const T *table) { - return !table || table->Verify(*this); - } - - // Verify a pointer (may be NULL) of any vector type. - template bool VerifyVector(const Vector *vec) const { - return !vec || VerifyVectorOrString(reinterpret_cast(vec), - sizeof(T)); - } - - // Verify a pointer (may be NULL) of a vector to struct. - template bool VerifyVector(const Vector *vec) const { - return VerifyVector(reinterpret_cast *>(vec)); - } - - // Verify a pointer (may be NULL) to string. - bool VerifyString(const String *str) const { - size_t end; - return !str || (VerifyVectorOrString(reinterpret_cast(str), - 1, &end) && - Verify(end, 1) && // Must have terminator - Check(buf_[end] == '\0')); // Terminating byte must be 0. - } - - // Common code between vectors and strings. - bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size, - size_t *end = nullptr) const { - auto veco = static_cast(vec - buf_); - // Check we can read the size field. - if (!Verify(veco)) return false; - // Check the whole array. If this is a string, the byte past the array - // must be 0. - auto size = ReadScalar(vec); - auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size; - if (!Check(size < max_elems)) - return false; // Protect against byte_size overflowing. - auto byte_size = sizeof(size) + elem_size * size; - if (end) *end = veco + byte_size; - return Verify(veco, byte_size); - } - - // Special case for string contents, after the above has been called. - bool VerifyVectorOfStrings(const Vector> *vec) const { - if (vec) { - for (uoffset_t i = 0; i < vec->size(); i++) { - if (!VerifyString(vec->Get(i))) return false; - } - } - return true; - } - - // Special case for table contents, after the above has been called. - template bool VerifyVectorOfTables(const Vector> *vec) { - if (vec) { - for (uoffset_t i = 0; i < vec->size(); i++) { - if (!vec->Get(i)->Verify(*this)) return false; - } - } - return true; - } - - __supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart( - const uint8_t *table) { - // Check the vtable offset. - auto tableo = static_cast(table - buf_); - if (!Verify(tableo)) return false; - // This offset may be signed, but doing the subtraction unsigned always - // gives the result we want. - auto vtableo = tableo - static_cast(ReadScalar(table)); - // Check the vtable size field, then check vtable fits in its entirety. - return VerifyComplexity() && Verify(vtableo) && - VerifyAlignment(ReadScalar(buf_ + vtableo)) && - Verify(vtableo, ReadScalar(buf_ + vtableo)); - } - - template - bool VerifyBufferFromStart(const char *identifier, size_t start) { - if (identifier && (size_ < 2 * sizeof(flatbuffers::uoffset_t) || - !BufferHasIdentifier(buf_ + start, identifier))) { - return false; - } - - // Call T::Verify, which must be in the generated code for this type. - auto o = VerifyOffset(start); - return o && reinterpret_cast(buf_ + start + o)->Verify(*this) - // clang-format off - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - && GetComputedSize() - #endif - ; - // clang-format on - } - - // Verify this whole buffer, starting with root type T. - template bool VerifyBuffer() { return VerifyBuffer(nullptr); } - - template bool VerifyBuffer(const char *identifier) { - return VerifyBufferFromStart(identifier, 0); - } - - template bool VerifySizePrefixedBuffer(const char *identifier) { - return Verify(0U) && - ReadScalar(buf_) == size_ - sizeof(uoffset_t) && - VerifyBufferFromStart(identifier, sizeof(uoffset_t)); - } - - uoffset_t VerifyOffset(size_t start) const { - if (!Verify(start)) return 0; - auto o = ReadScalar(buf_ + start); - // May not point to itself. - if (!Check(o != 0)) return 0; - // Can't wrap around / buffers are max 2GB. - if (!Check(static_cast(o) >= 0)) return 0; - // Must be inside the buffer to create a pointer from it (pointer outside - // buffer is UB). - if (!Verify(start + o, 1)) return 0; - return o; - } - - uoffset_t VerifyOffset(const uint8_t *base, voffset_t start) const { - return VerifyOffset(static_cast(base - buf_) + start); - } - - // Called at the start of a table to increase counters measuring data - // structure depth and amount, and possibly bails out with false if - // limits set by the constructor have been hit. Needs to be balanced - // with EndTable(). - bool VerifyComplexity() { - depth_++; - num_tables_++; - return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_); - } - - // Called at the end of a table to pop the depth count. - bool EndTable() { - depth_--; - return true; - } - - // Returns the message size in bytes - size_t GetComputedSize() const { - // clang-format off - #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE - uintptr_t size = upper_bound_; - // Align the size to uoffset_t - size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1); - return (size > size_) ? 0 : size; - #else - // Must turn on FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE for this to work. - (void)upper_bound_; - FLATBUFFERS_ASSERT(false); - return 0; - #endif - // clang-format on - } - - private: - const uint8_t *buf_; - size_t size_; - uoffset_t depth_; - uoffset_t max_depth_; - uoffset_t num_tables_; - uoffset_t max_tables_; - mutable size_t upper_bound_; - bool check_alignment_; -}; - -// Convenient way to bundle a buffer and its length, to pass it around -// typed by its root. -// A BufferRef does not own its buffer. -struct BufferRefBase {}; // for std::is_base_of -template struct BufferRef : BufferRefBase { - BufferRef() : buf(nullptr), len(0), must_free(false) {} - BufferRef(uint8_t *_buf, uoffset_t _len) - : buf(_buf), len(_len), must_free(false) {} - - ~BufferRef() { - if (must_free) free(buf); - } - - const T *GetRoot() const { return flatbuffers::GetRoot(buf); } - - bool Verify() { - Verifier verifier(buf, len); - return verifier.VerifyBuffer(nullptr); - } - - uint8_t *buf; - uoffset_t len; - bool must_free; -}; - -// "structs" are flat structures that do not have an offset table, thus -// always have all members present and do not support forwards/backwards -// compatible extensions. - -class Struct FLATBUFFERS_FINAL_CLASS { - public: - template T GetField(uoffset_t o) const { - return ReadScalar(&data_[o]); - } - - template T GetStruct(uoffset_t o) const { - return reinterpret_cast(&data_[o]); - } - - const uint8_t *GetAddressOf(uoffset_t o) const { return &data_[o]; } - uint8_t *GetAddressOf(uoffset_t o) { return &data_[o]; } - - private: - // private constructor & copy constructor: you obtain instances of this - // class by pointing to existing data only - Struct(); - Struct(const Struct &); - Struct &operator=(const Struct &); - - uint8_t data_[1]; -}; - -// "tables" use an offset table (possibly shared) that allows fields to be -// omitted and added at will, but uses an extra indirection to read. -class Table { - public: - const uint8_t *GetVTable() const { - return data_ - ReadScalar(data_); - } - - // This gets the field offset for any of the functions below it, or 0 - // if the field was not present. - voffset_t GetOptionalFieldOffset(voffset_t field) const { - // The vtable offset is always at the start. - auto vtable = GetVTable(); - // The first element is the size of the vtable (fields + type id + itself). - auto vtsize = ReadScalar(vtable); - // If the field we're accessing is outside the vtable, we're reading older - // data, so it's the same as if the offset was 0 (not present). - return field < vtsize ? ReadScalar(vtable + field) : 0; - } - - template T GetField(voffset_t field, T defaultval) const { - auto field_offset = GetOptionalFieldOffset(field); - return field_offset ? ReadScalar(data_ + field_offset) : defaultval; - } - - template P GetPointer(voffset_t field) { - auto field_offset = GetOptionalFieldOffset(field); - auto p = data_ + field_offset; - return field_offset ? reinterpret_cast

(p + ReadScalar(p)) - : nullptr; - } - template P GetPointer(voffset_t field) const { - return const_cast(this)->GetPointer

(field); - } - - template P GetStruct(voffset_t field) const { - auto field_offset = GetOptionalFieldOffset(field); - auto p = const_cast(data_ + field_offset); - return field_offset ? reinterpret_cast

(p) : nullptr; - } - - template bool SetField(voffset_t field, T val, T def) { - auto field_offset = GetOptionalFieldOffset(field); - if (!field_offset) return IsTheSameAs(val, def); - WriteScalar(data_ + field_offset, val); - return true; - } - - bool SetPointer(voffset_t field, const uint8_t *val) { - auto field_offset = GetOptionalFieldOffset(field); - if (!field_offset) return false; - WriteScalar(data_ + field_offset, - static_cast(val - (data_ + field_offset))); - return true; - } - - uint8_t *GetAddressOf(voffset_t field) { - auto field_offset = GetOptionalFieldOffset(field); - return field_offset ? data_ + field_offset : nullptr; - } - const uint8_t *GetAddressOf(voffset_t field) const { - return const_cast

(this)->GetAddressOf(field); - } - - bool CheckField(voffset_t field) const { - return GetOptionalFieldOffset(field) != 0; - } - - // Verify the vtable of this table. - // Call this once per table, followed by VerifyField once per field. - bool VerifyTableStart(Verifier &verifier) const { - return verifier.VerifyTableStart(data_); - } - - // Verify a particular field. - template - bool VerifyField(const Verifier &verifier, voffset_t field) const { - // Calling GetOptionalFieldOffset should be safe now thanks to - // VerifyTable(). - auto field_offset = GetOptionalFieldOffset(field); - // Check the actual field. - return !field_offset || verifier.Verify(data_, field_offset); - } - - // VerifyField for required fields. - template - bool VerifyFieldRequired(const Verifier &verifier, voffset_t field) const { - auto field_offset = GetOptionalFieldOffset(field); - return verifier.Check(field_offset != 0) && - verifier.Verify(data_, field_offset); - } - - // Versions for offsets. - bool VerifyOffset(const Verifier &verifier, voffset_t field) const { - auto field_offset = GetOptionalFieldOffset(field); - return !field_offset || verifier.VerifyOffset(data_, field_offset); - } - - bool VerifyOffsetRequired(const Verifier &verifier, voffset_t field) const { - auto field_offset = GetOptionalFieldOffset(field); - return verifier.Check(field_offset != 0) && - verifier.VerifyOffset(data_, field_offset); - } - - private: - // private constructor & copy constructor: you obtain instances of this - // class by pointing to existing data only - Table(); - Table(const Table &other); - Table &operator=(const Table &); - - uint8_t data_[1]; -}; - -template -void FlatBufferBuilder::Required(Offset table, voffset_t field) { - auto table_ptr = reinterpret_cast(buf_.data_at(table.o)); - bool ok = table_ptr->GetOptionalFieldOffset(field) != 0; - // If this fails, the caller will show what field needs to be set. - FLATBUFFERS_ASSERT(ok); - (void)ok; -} - -/// @brief This can compute the start of a FlatBuffer from a root pointer, i.e. -/// it is the opposite transformation of GetRoot(). -/// This may be useful if you want to pass on a root and have the recipient -/// delete the buffer afterwards. -inline const uint8_t *GetBufferStartFromRootPointer(const void *root) { - auto table = reinterpret_cast(root); - auto vtable = table->GetVTable(); - // Either the vtable is before the root or after the root. - auto start = (std::min)(vtable, reinterpret_cast(root)); - // Align to at least sizeof(uoffset_t). - start = reinterpret_cast(reinterpret_cast(start) & - ~(sizeof(uoffset_t) - 1)); - // Additionally, there may be a file_identifier in the buffer, and the root - // offset. The buffer may have been aligned to any size between - // sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align"). - // Sadly, the exact alignment is only known when constructing the buffer, - // since it depends on the presence of values with said alignment properties. - // So instead, we simply look at the next uoffset_t values (root, - // file_identifier, and alignment padding) to see which points to the root. - // None of the other values can "impersonate" the root since they will either - // be 0 or four ASCII characters. - static_assert(FlatBufferBuilder::kFileIdentifierLength == sizeof(uoffset_t), - "file_identifier is assumed to be the same size as uoffset_t"); - for (auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT / sizeof(uoffset_t) + 1; - possible_roots; possible_roots--) { - start -= sizeof(uoffset_t); - if (ReadScalar(start) + start == - reinterpret_cast(root)) - return start; - } - // We didn't find the root, either the "root" passed isn't really a root, - // or the buffer is corrupt. - // Assert, because calling this function with bad data may cause reads - // outside of buffer boundaries. - FLATBUFFERS_ASSERT(false); - return nullptr; -} - -/// @brief This return the prefixed size of a FlatBuffer. -inline uoffset_t GetPrefixedSize(const uint8_t *buf) { - return ReadScalar(buf); -} - -// Base class for native objects (FlatBuffer data de-serialized into native -// C++ data structures). -// Contains no functionality, purely documentative. -struct NativeTable {}; - -/// @brief Function types to be used with resolving hashes into objects and -/// back again. The resolver gets a pointer to a field inside an object API -/// object that is of the type specified in the schema using the attribute -/// `cpp_type` (it is thus important whatever you write to this address -/// matches that type). The value of this field is initially null, so you -/// may choose to implement a delayed binding lookup using this function -/// if you wish. The resolver does the opposite lookup, for when the object -/// is being serialized again. -typedef uint64_t hash_value_t; -// clang-format off -#ifdef FLATBUFFERS_CPP98_STL - typedef void (*resolver_function_t)(void **pointer_adr, hash_value_t hash); - typedef hash_value_t (*rehasher_function_t)(void *pointer); -#else - typedef std::function - resolver_function_t; - typedef std::function rehasher_function_t; -#endif -// clang-format on - -// Helper function to test if a field is present, using any of the field -// enums in the generated code. -// `table` must be a generated table type. Since this is a template parameter, -// this is not typechecked to be a subclass of Table, so beware! -// Note: this function will return false for fields equal to the default -// value, since they're not stored in the buffer (unless force_defaults was -// used). -template -bool IsFieldPresent(const T *table, typename T::FlatBuffersVTableOffset field) { - // Cast, since Table is a private baseclass of any table types. - return reinterpret_cast(table)->CheckField( - static_cast(field)); -} - -// Utility function for reverse lookups on the EnumNames*() functions -// (in the generated C++ code) -// names must be NULL terminated. -inline int LookupEnum(const char **names, const char *name) { - for (const char **p = names; *p; p++) - if (!strcmp(*p, name)) return static_cast(p - names); - return -1; -} - -// These macros allow us to layout a struct with a guarantee that they'll end -// up looking the same on different compilers and platforms. -// It does this by disallowing the compiler to do any padding, and then -// does padding itself by inserting extra padding fields that make every -// element aligned to its own size. -// Additionally, it manually sets the alignment of the struct as a whole, -// which is typically its largest element, or a custom size set in the schema -// by the force_align attribute. -// These are used in the generated code only. - -// clang-format off -#if defined(_MSC_VER) - #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \ - __pragma(pack(1)) \ - struct __declspec(align(alignment)) - #define FLATBUFFERS_STRUCT_END(name, size) \ - __pragma(pack()) \ - static_assert(sizeof(name) == size, "compiler breaks packing rules") -#elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) - #define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \ - _Pragma("pack(1)") \ - struct __attribute__((aligned(alignment))) - #define FLATBUFFERS_STRUCT_END(name, size) \ - _Pragma("pack()") \ - static_assert(sizeof(name) == size, "compiler breaks packing rules") -#else - #error Unknown compiler, please define structure alignment macros -#endif -// clang-format on - -// Minimal reflection via code generation. -// Besides full-fat reflection (see reflection.h) and parsing/printing by -// loading schemas (see idl.h), we can also have code generation for mimimal -// reflection data which allows pretty-printing and other uses without needing -// a schema or a parser. -// Generate code with --reflect-types (types only) or --reflect-names (names -// also) to enable. -// See minireflect.h for utilities using this functionality. - -// These types are organized slightly differently as the ones in idl.h. -enum SequenceType { ST_TABLE, ST_STRUCT, ST_UNION, ST_ENUM }; - -// Scalars have the same order as in idl.h -// clang-format off -#define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \ - ET(ET_UTYPE) \ - ET(ET_BOOL) \ - ET(ET_CHAR) \ - ET(ET_UCHAR) \ - ET(ET_SHORT) \ - ET(ET_USHORT) \ - ET(ET_INT) \ - ET(ET_UINT) \ - ET(ET_LONG) \ - ET(ET_ULONG) \ - ET(ET_FLOAT) \ - ET(ET_DOUBLE) \ - ET(ET_STRING) \ - ET(ET_SEQUENCE) // See SequenceType. - -enum ElementaryType { - #define FLATBUFFERS_ET(E) E, - FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET) - #undef FLATBUFFERS_ET -}; - -inline const char * const *ElementaryTypeNames() { - static const char * const names[] = { - #define FLATBUFFERS_ET(E) #E, - FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET) - #undef FLATBUFFERS_ET - }; - return names; -} -// clang-format on - -// Basic type info cost just 16bits per field! -struct TypeCode { - uint16_t base_type : 4; // ElementaryType - uint16_t is_vector : 1; - int16_t sequence_ref : 11; // Index into type_refs below, or -1 for none. -}; - -static_assert(sizeof(TypeCode) == 2, "TypeCode"); - -struct TypeTable; - -// Signature of the static method present in each type. -typedef const TypeTable *(*TypeFunction)(); - -struct TypeTable { - SequenceType st; - size_t num_elems; // of type_codes, values, names (but not type_refs). - const TypeCode *type_codes; // num_elems count - const TypeFunction *type_refs; // less than num_elems entries (see TypeCode). - const int64_t *values; // Only set for non-consecutive enum/union or structs. - const char *const *names; // Only set if compiled with --reflect-names. -}; - -// String which identifies the current version of FlatBuffers. -// flatbuffer_version_string is used by Google developers to identify which -// applications uploaded to Google Play are using this library. This allows -// the development team at Google to determine the popularity of the library. -// How it works: Applications that are uploaded to the Google Play Store are -// scanned for this version string. We track which applications are using it -// to measure popularity. You are free to remove it (of course) but we would -// appreciate if you left it in. - -// Weak linkage is culled by VS & doesn't work on cygwin. -// clang-format off -#if !defined(_WIN32) && !defined(__CYGWIN__) - -extern volatile __attribute__((weak)) const char *flatbuffer_version_string; -volatile __attribute__((weak)) const char *flatbuffer_version_string = - "FlatBuffers " - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "." - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "." - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION); - -#endif // !defined(_WIN32) && !defined(__CYGWIN__) - -#define FLATBUFFERS_DEFINE_BITMASK_OPERATORS(E, T)\ - inline E operator | (E lhs, E rhs){\ - return E(T(lhs) | T(rhs));\ - }\ - inline E operator & (E lhs, E rhs){\ - return E(T(lhs) & T(rhs));\ - }\ - inline E operator ^ (E lhs, E rhs){\ - return E(T(lhs) ^ T(rhs));\ - }\ - inline E operator ~ (E lhs){\ - return E(~T(lhs));\ - }\ - inline E operator |= (E &lhs, E rhs){\ - lhs = lhs | rhs;\ - return lhs;\ - }\ - inline E operator &= (E &lhs, E rhs){\ - lhs = lhs & rhs;\ - return lhs;\ - }\ - inline E operator ^= (E &lhs, E rhs){\ - lhs = lhs ^ rhs;\ - return lhs;\ - }\ - inline bool operator !(E rhs) \ - {\ - return !bool(T(rhs)); \ - } -/// @endcond -} // namespace flatbuffers - -// clang-format on - -#endif // FLATBUFFERS_H_ diff --git a/daemon/src/External/include/flatbuffers/flatc.h b/daemon/src/External/include/flatbuffers/flatc.h deleted file mode 100644 index 5e2709e7..00000000 --- a/daemon/src/External/include/flatbuffers/flatc.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_FLATC_H_ -#define FLATBUFFERS_FLATC_H_ - -#include -#include -#include - -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -extern void LogCompilerWarn(const std::string &warn); -extern void LogCompilerError(const std::string &err); - -class FlatCompiler { - public: - // Output generator for the various programming languages and formats we - // support. - struct Generator { - typedef bool (*GenerateFn)(const flatbuffers::Parser &parser, - const std::string &path, - const std::string &file_name); - typedef std::string (*MakeRuleFn)(const flatbuffers::Parser &parser, - const std::string &path, - const std::string &file_name); - - GenerateFn generate; - const char *generator_opt_short; - const char *generator_opt_long; - const char *lang_name; - bool schema_only; - GenerateFn generateGRPC; - flatbuffers::IDLOptions::Language lang; - const char *generator_help; - MakeRuleFn make_rule; - }; - - typedef void (*WarnFn)(const FlatCompiler *flatc, const std::string &warn, - bool show_exe_name); - - typedef void (*ErrorFn)(const FlatCompiler *flatc, const std::string &err, - bool usage, bool show_exe_name); - - // Parameters required to initialize the FlatCompiler. - struct InitParams { - InitParams() - : generators(nullptr), - num_generators(0), - warn_fn(nullptr), - error_fn(nullptr) {} - - const Generator *generators; - size_t num_generators; - WarnFn warn_fn; - ErrorFn error_fn; - }; - - explicit FlatCompiler(const InitParams ¶ms) : params_(params) {} - - int Compile(int argc, const char **argv); - - std::string GetUsageString(const char *program_name) const; - - private: - void ParseFile(flatbuffers::Parser &parser, const std::string &filename, - const std::string &contents, - std::vector &include_directories) const; - - void LoadBinarySchema(Parser &parser, const std::string &filename, - const std::string &contents); - - void Warn(const std::string &warn, bool show_exe_name = true) const; - - void Error(const std::string &err, bool usage = true, - bool show_exe_name = true) const; - - InitParams params_; -}; - -} // namespace flatbuffers - -#endif // FLATBUFFERS_FLATC_H_ diff --git a/daemon/src/External/include/flatbuffers/flexbuffers.h b/daemon/src/External/include/flatbuffers/flexbuffers.h deleted file mode 100644 index 7e55a7f6..00000000 --- a/daemon/src/External/include/flatbuffers/flexbuffers.h +++ /dev/null @@ -1,1618 +0,0 @@ -/* - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_FLEXBUFFERS_H_ -#define FLATBUFFERS_FLEXBUFFERS_H_ - -#include -// Used to select STL variant. -#include "flatbuffers/base.h" -// We use the basic binary writing functions from the regular FlatBuffers. -#include "flatbuffers/util.h" - -#ifdef _MSC_VER -# include -#endif - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4127) // C4127: conditional expression is constant -#endif - -namespace flexbuffers { - -class Reference; -class Map; - -// These are used in the lower 2 bits of a type field to determine the size of -// the elements (and or size field) of the item pointed to (e.g. vector). -enum BitWidth { - BIT_WIDTH_8 = 0, - BIT_WIDTH_16 = 1, - BIT_WIDTH_32 = 2, - BIT_WIDTH_64 = 3, -}; - -// These are used as the upper 6 bits of a type field to indicate the actual -// type. -enum Type { - FBT_NULL = 0, - FBT_INT = 1, - FBT_UINT = 2, - FBT_FLOAT = 3, - // Types above stored inline, types below store an offset. - FBT_KEY = 4, - FBT_STRING = 5, - FBT_INDIRECT_INT = 6, - FBT_INDIRECT_UINT = 7, - FBT_INDIRECT_FLOAT = 8, - FBT_MAP = 9, - FBT_VECTOR = 10, // Untyped. - FBT_VECTOR_INT = 11, // Typed any size (stores no type table). - FBT_VECTOR_UINT = 12, - FBT_VECTOR_FLOAT = 13, - FBT_VECTOR_KEY = 14, - // DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead. - // Read test.cpp/FlexBuffersDeprecatedTest() for details on why. - FBT_VECTOR_STRING_DEPRECATED = 15, - FBT_VECTOR_INT2 = 16, // Typed tuple (no type table, no size field). - FBT_VECTOR_UINT2 = 17, - FBT_VECTOR_FLOAT2 = 18, - FBT_VECTOR_INT3 = 19, // Typed triple (no type table, no size field). - FBT_VECTOR_UINT3 = 20, - FBT_VECTOR_FLOAT3 = 21, - FBT_VECTOR_INT4 = 22, // Typed quad (no type table, no size field). - FBT_VECTOR_UINT4 = 23, - FBT_VECTOR_FLOAT4 = 24, - FBT_BLOB = 25, - FBT_BOOL = 26, - FBT_VECTOR_BOOL = - 36, // To Allow the same type of conversion of type to vector type -}; - -inline bool IsInline(Type t) { return t <= FBT_FLOAT || t == FBT_BOOL; } - -inline bool IsTypedVectorElementType(Type t) { - return (t >= FBT_INT && t <= FBT_STRING) || t == FBT_BOOL; -} - -inline bool IsTypedVector(Type t) { - return (t >= FBT_VECTOR_INT && t <= FBT_VECTOR_STRING_DEPRECATED) || - t == FBT_VECTOR_BOOL; -} - -inline bool IsFixedTypedVector(Type t) { - return t >= FBT_VECTOR_INT2 && t <= FBT_VECTOR_FLOAT4; -} - -inline Type ToTypedVector(Type t, size_t fixed_len = 0) { - FLATBUFFERS_ASSERT(IsTypedVectorElementType(t)); - switch (fixed_len) { - case 0: return static_cast(t - FBT_INT + FBT_VECTOR_INT); - case 2: return static_cast(t - FBT_INT + FBT_VECTOR_INT2); - case 3: return static_cast(t - FBT_INT + FBT_VECTOR_INT3); - case 4: return static_cast(t - FBT_INT + FBT_VECTOR_INT4); - default: FLATBUFFERS_ASSERT(0); return FBT_NULL; - } -} - -inline Type ToTypedVectorElementType(Type t) { - FLATBUFFERS_ASSERT(IsTypedVector(t)); - return static_cast(t - FBT_VECTOR_INT + FBT_INT); -} - -inline Type ToFixedTypedVectorElementType(Type t, uint8_t *len) { - FLATBUFFERS_ASSERT(IsFixedTypedVector(t)); - auto fixed_type = t - FBT_VECTOR_INT2; - *len = static_cast(fixed_type / 3 + - 2); // 3 types each, starting from length 2. - return static_cast(fixed_type % 3 + FBT_INT); -} - -// TODO: implement proper support for 8/16bit floats, or decide not to -// support them. -typedef int16_t half; -typedef int8_t quarter; - -// TODO: can we do this without conditionals using intrinsics or inline asm -// on some platforms? Given branch prediction the method below should be -// decently quick, but it is the most frequently executed function. -// We could do an (unaligned) 64-bit read if we ifdef out the platforms for -// which that doesn't work (or where we'd read into un-owned memory). -template -R ReadSizedScalar(const uint8_t *data, uint8_t byte_width) { - return byte_width < 4 - ? (byte_width < 2 - ? static_cast(flatbuffers::ReadScalar(data)) - : static_cast(flatbuffers::ReadScalar(data))) - : (byte_width < 8 - ? static_cast(flatbuffers::ReadScalar(data)) - : static_cast(flatbuffers::ReadScalar(data))); -} - -inline int64_t ReadInt64(const uint8_t *data, uint8_t byte_width) { - return ReadSizedScalar( - data, byte_width); -} - -inline uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width) { - // This is the "hottest" function (all offset lookups use this), so worth - // optimizing if possible. - // TODO: GCC apparently replaces memcpy by a rep movsb, but only if count is a - // constant, which here it isn't. Test if memcpy is still faster than - // the conditionals in ReadSizedScalar. Can also use inline asm. - // clang-format off - #if defined(_MSC_VER) && (defined(_M_X64) || defined _M_IX86) - uint64_t u = 0; - __movsb(reinterpret_cast(&u), - reinterpret_cast(data), byte_width); - return flatbuffers::EndianScalar(u); - #else - return ReadSizedScalar( - data, byte_width); - #endif - // clang-format on -} - -inline double ReadDouble(const uint8_t *data, uint8_t byte_width) { - return ReadSizedScalar(data, - byte_width); -} - -inline const uint8_t *Indirect(const uint8_t *offset, uint8_t byte_width) { - return offset - ReadUInt64(offset, byte_width); -} - -template const uint8_t *Indirect(const uint8_t *offset) { - return offset - flatbuffers::ReadScalar(offset); -} - -inline BitWidth WidthU(uint64_t u) { -#define FLATBUFFERS_GET_FIELD_BIT_WIDTH(value, width) \ - { \ - if (!((u) & ~((1ULL << (width)) - 1ULL))) return BIT_WIDTH_##width; \ - } - FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 8); - FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 16); - FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 32); -#undef FLATBUFFERS_GET_FIELD_BIT_WIDTH - return BIT_WIDTH_64; -} - -inline BitWidth WidthI(int64_t i) { - auto u = static_cast(i) << 1; - return WidthU(i >= 0 ? u : ~u); -} - -inline BitWidth WidthF(double f) { - return static_cast(static_cast(f)) == f ? BIT_WIDTH_32 - : BIT_WIDTH_64; -} - -// Base class of all types below. -// Points into the data buffer and allows access to one type. -class Object { - public: - Object(const uint8_t *data, uint8_t byte_width) - : data_(data), byte_width_(byte_width) {} - - protected: - const uint8_t *data_; - uint8_t byte_width_; -}; - -// Object that has a size, obtained either from size prefix, or elsewhere. -class Sized : public Object { - public: - // Size prefix. - Sized(const uint8_t *data, uint8_t byte_width) - : Object(data, byte_width), size_(read_size()) {} - // Manual size. - Sized(const uint8_t *data, uint8_t byte_width, size_t sz) - : Object(data, byte_width), size_(sz) {} - size_t size() const { return size_; } - // Access size stored in `byte_width_` bytes before data_ pointer. - size_t read_size() const { - return static_cast(ReadUInt64(data_ - byte_width_, byte_width_)); - } - - protected: - size_t size_; -}; - -class String : public Sized { - public: - // Size prefix. - String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {} - // Manual size. - String(const uint8_t *data, uint8_t byte_width, size_t sz) - : Sized(data, byte_width, sz) {} - - size_t length() const { return size(); } - const char *c_str() const { return reinterpret_cast(data_); } - std::string str() const { return std::string(c_str(), size()); } - - static String EmptyString() { - static const char *empty_string = ""; - return String(reinterpret_cast(empty_string), 1, 0); - } - bool IsTheEmptyString() const { return data_ == EmptyString().data_; } -}; - -class Blob : public Sized { - public: - Blob(const uint8_t *data_buf, uint8_t byte_width) - : Sized(data_buf, byte_width) {} - - static Blob EmptyBlob() { - static const uint8_t empty_blob[] = { 0 /*len*/ }; - return Blob(empty_blob + 1, 1); - } - bool IsTheEmptyBlob() const { return data_ == EmptyBlob().data_; } - const uint8_t *data() const { return data_; } -}; - -class Vector : public Sized { - public: - Vector(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {} - - Reference operator[](size_t i) const; - - static Vector EmptyVector() { - static const uint8_t empty_vector[] = { 0 /*len*/ }; - return Vector(empty_vector + 1, 1); - } - bool IsTheEmptyVector() const { return data_ == EmptyVector().data_; } -}; - -class TypedVector : public Sized { - public: - TypedVector(const uint8_t *data, uint8_t byte_width, Type element_type) - : Sized(data, byte_width), type_(element_type) {} - - Reference operator[](size_t i) const; - - static TypedVector EmptyTypedVector() { - static const uint8_t empty_typed_vector[] = { 0 /*len*/ }; - return TypedVector(empty_typed_vector + 1, 1, FBT_INT); - } - bool IsTheEmptyVector() const { - return data_ == TypedVector::EmptyTypedVector().data_; - } - - Type ElementType() { return type_; } - - friend Reference; - - private: - Type type_; - - friend Map; -}; - -class FixedTypedVector : public Object { - public: - FixedTypedVector(const uint8_t *data, uint8_t byte_width, Type element_type, - uint8_t len) - : Object(data, byte_width), type_(element_type), len_(len) {} - - Reference operator[](size_t i) const; - - static FixedTypedVector EmptyFixedTypedVector() { - static const uint8_t fixed_empty_vector[] = { 0 /* unused */ }; - return FixedTypedVector(fixed_empty_vector, 1, FBT_INT, 0); - } - bool IsTheEmptyFixedTypedVector() const { - return data_ == FixedTypedVector::EmptyFixedTypedVector().data_; - } - - Type ElementType() { return type_; } - uint8_t size() { return len_; } - - private: - Type type_; - uint8_t len_; -}; - -class Map : public Vector { - public: - Map(const uint8_t *data, uint8_t byte_width) : Vector(data, byte_width) {} - - Reference operator[](const char *key) const; - Reference operator[](const std::string &key) const; - - Vector Values() const { return Vector(data_, byte_width_); } - - TypedVector Keys() const { - const size_t num_prefixed_fields = 3; - auto keys_offset = data_ - byte_width_ * num_prefixed_fields; - return TypedVector(Indirect(keys_offset, byte_width_), - static_cast( - ReadUInt64(keys_offset + byte_width_, byte_width_)), - FBT_KEY); - } - - static Map EmptyMap() { - static const uint8_t empty_map[] = { - 0 /*keys_len*/, 0 /*keys_offset*/, 1 /*keys_width*/, 0 /*len*/ - }; - return Map(empty_map + 4, 1); - } - - bool IsTheEmptyMap() const { return data_ == EmptyMap().data_; } -}; - -template -void AppendToString(std::string &s, T &&v, bool keys_quoted) { - s += "[ "; - for (size_t i = 0; i < v.size(); i++) { - if (i) s += ", "; - v[i].ToString(true, keys_quoted, s); - } - s += " ]"; -} - -class Reference { - public: - Reference() - : data_(nullptr), - parent_width_(0), - byte_width_(BIT_WIDTH_8), - type_(FBT_NULL) {} - - Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width, - Type type) - : data_(data), - parent_width_(parent_width), - byte_width_(byte_width), - type_(type) {} - - Reference(const uint8_t *data, uint8_t parent_width, uint8_t packed_type) - : data_(data), parent_width_(parent_width) { - byte_width_ = 1U << static_cast(packed_type & 3); - type_ = static_cast(packed_type >> 2); - } - - Type GetType() const { return type_; } - - bool IsNull() const { return type_ == FBT_NULL; } - bool IsBool() const { return type_ == FBT_BOOL; } - bool IsInt() const { return type_ == FBT_INT || type_ == FBT_INDIRECT_INT; } - bool IsUInt() const { - return type_ == FBT_UINT || type_ == FBT_INDIRECT_UINT; - } - bool IsIntOrUint() const { return IsInt() || IsUInt(); } - bool IsFloat() const { - return type_ == FBT_FLOAT || type_ == FBT_INDIRECT_FLOAT; - } - bool IsNumeric() const { return IsIntOrUint() || IsFloat(); } - bool IsString() const { return type_ == FBT_STRING; } - bool IsKey() const { return type_ == FBT_KEY; } - bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; } - bool IsUntypedVector() const { return type_ == FBT_VECTOR; } - bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); } - bool IsFixedTypedVector() const { - return flexbuffers::IsFixedTypedVector(type_); - } - bool IsAnyVector() const { - return (IsTypedVector() || IsFixedTypedVector() || IsVector()); - } - bool IsMap() const { return type_ == FBT_MAP; } - bool IsBlob() const { return type_ == FBT_BLOB; } - bool AsBool() const { - return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_) - : AsUInt64()) != 0; - } - - // Reads any type as a int64_t. Never fails, does most sensible conversion. - // Truncates floats, strings are attempted to be parsed for a number, - // vectors/maps return their size. Returns 0 if all else fails. - int64_t AsInt64() const { - if (type_ == FBT_INT) { - // A fast path for the common case. - return ReadInt64(data_, parent_width_); - } else - switch (type_) { - case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_); - case FBT_UINT: return ReadUInt64(data_, parent_width_); - case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_); - case FBT_FLOAT: - return static_cast(ReadDouble(data_, parent_width_)); - case FBT_INDIRECT_FLOAT: - return static_cast(ReadDouble(Indirect(), byte_width_)); - case FBT_NULL: return 0; - case FBT_STRING: return flatbuffers::StringToInt(AsString().c_str()); - case FBT_VECTOR: return static_cast(AsVector().size()); - case FBT_BOOL: return ReadInt64(data_, parent_width_); - default: - // Convert other things to int. - return 0; - } - } - - // TODO: could specialize these to not use AsInt64() if that saves - // extension ops in generated code, and use a faster op than ReadInt64. - int32_t AsInt32() const { return static_cast(AsInt64()); } - int16_t AsInt16() const { return static_cast(AsInt64()); } - int8_t AsInt8() const { return static_cast(AsInt64()); } - - uint64_t AsUInt64() const { - if (type_ == FBT_UINT) { - // A fast path for the common case. - return ReadUInt64(data_, parent_width_); - } else - switch (type_) { - case FBT_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_); - case FBT_INT: return ReadInt64(data_, parent_width_); - case FBT_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_); - case FBT_FLOAT: - return static_cast(ReadDouble(data_, parent_width_)); - case FBT_INDIRECT_FLOAT: - return static_cast(ReadDouble(Indirect(), byte_width_)); - case FBT_NULL: return 0; - case FBT_STRING: return flatbuffers::StringToUInt(AsString().c_str()); - case FBT_VECTOR: return static_cast(AsVector().size()); - case FBT_BOOL: return ReadUInt64(data_, parent_width_); - default: - // Convert other things to uint. - return 0; - } - } - - uint32_t AsUInt32() const { return static_cast(AsUInt64()); } - uint16_t AsUInt16() const { return static_cast(AsUInt64()); } - uint8_t AsUInt8() const { return static_cast(AsUInt64()); } - - double AsDouble() const { - if (type_ == FBT_FLOAT) { - // A fast path for the common case. - return ReadDouble(data_, parent_width_); - } else - switch (type_) { - case FBT_INDIRECT_FLOAT: return ReadDouble(Indirect(), byte_width_); - case FBT_INT: - return static_cast(ReadInt64(data_, parent_width_)); - case FBT_UINT: - return static_cast(ReadUInt64(data_, parent_width_)); - case FBT_INDIRECT_INT: - return static_cast(ReadInt64(Indirect(), byte_width_)); - case FBT_INDIRECT_UINT: - return static_cast(ReadUInt64(Indirect(), byte_width_)); - case FBT_NULL: return 0.0; - case FBT_STRING: { - double d; - flatbuffers::StringToNumber(AsString().c_str(), &d); - return d; - } - case FBT_VECTOR: return static_cast(AsVector().size()); - case FBT_BOOL: - return static_cast(ReadUInt64(data_, parent_width_)); - default: - // Convert strings and other things to float. - return 0; - } - } - - float AsFloat() const { return static_cast(AsDouble()); } - - const char *AsKey() const { - if (type_ == FBT_KEY || type_ == FBT_STRING) { - return reinterpret_cast(Indirect()); - } else { - return ""; - } - } - - // This function returns the empty string if you try to read something that - // is not a string or key. - String AsString() const { - if (type_ == FBT_STRING) { - return String(Indirect(), byte_width_); - } else if (type_ == FBT_KEY) { - auto key = Indirect(); - return String(key, byte_width_, - strlen(reinterpret_cast(key))); - } else { - return String::EmptyString(); - } - } - - // Unlike AsString(), this will convert any type to a std::string. - std::string ToString() const { - std::string s; - ToString(false, false, s); - return s; - } - - // Convert any type to a JSON-like string. strings_quoted determines if - // string values at the top level receive "" quotes (inside other values - // they always do). keys_quoted determines if keys are quoted, at any level. - // TODO(wvo): add further options to have indentation/newlines. - void ToString(bool strings_quoted, bool keys_quoted, std::string &s) const { - if (type_ == FBT_STRING) { - String str(Indirect(), byte_width_); - if (strings_quoted) { - flatbuffers::EscapeString(str.c_str(), str.length(), &s, true, false); - } else { - s.append(str.c_str(), str.length()); - } - } else if (IsKey()) { - auto str = AsKey(); - if (keys_quoted) { - flatbuffers::EscapeString(str, strlen(str), &s, true, false); - } else { - s += str; - } - } else if (IsInt()) { - s += flatbuffers::NumToString(AsInt64()); - } else if (IsUInt()) { - s += flatbuffers::NumToString(AsUInt64()); - } else if (IsFloat()) { - s += flatbuffers::NumToString(AsDouble()); - } else if (IsNull()) { - s += "null"; - } else if (IsBool()) { - s += AsBool() ? "true" : "false"; - } else if (IsMap()) { - s += "{ "; - auto m = AsMap(); - auto keys = m.Keys(); - auto vals = m.Values(); - for (size_t i = 0; i < keys.size(); i++) { - keys[i].ToString(true, keys_quoted, s); - s += ": "; - vals[i].ToString(true, keys_quoted, s); - if (i < keys.size() - 1) s += ", "; - } - s += " }"; - } else if (IsVector()) { - AppendToString(s, AsVector(), keys_quoted); - } else if (IsTypedVector()) { - AppendToString(s, AsTypedVector(), keys_quoted); - } else if (IsFixedTypedVector()) { - AppendToString(s, AsFixedTypedVector(), keys_quoted); - } else if (IsBlob()) { - auto blob = AsBlob(); - flatbuffers::EscapeString(reinterpret_cast(blob.data()), - blob.size(), &s, true, false); - } else { - s += "(?)"; - } - } - - // This function returns the empty blob if you try to read a not-blob. - // Strings can be viewed as blobs too. - Blob AsBlob() const { - if (type_ == FBT_BLOB || type_ == FBT_STRING) { - return Blob(Indirect(), byte_width_); - } else { - return Blob::EmptyBlob(); - } - } - - // This function returns the empty vector if you try to read a not-vector. - // Maps can be viewed as vectors too. - Vector AsVector() const { - if (type_ == FBT_VECTOR || type_ == FBT_MAP) { - return Vector(Indirect(), byte_width_); - } else { - return Vector::EmptyVector(); - } - } - - TypedVector AsTypedVector() const { - if (IsTypedVector()) { - auto tv = - TypedVector(Indirect(), byte_width_, ToTypedVectorElementType(type_)); - if (tv.type_ == FBT_STRING) { - // These can't be accessed as strings, since we don't know the bit-width - // of the size field, see the declaration of - // FBT_VECTOR_STRING_DEPRECATED above for details. - // We change the type here to be keys, which are a subtype of strings, - // and will ignore the size field. This will truncate strings with - // embedded nulls. - tv.type_ = FBT_KEY; - } - return tv; - } else { - return TypedVector::EmptyTypedVector(); - } - } - - FixedTypedVector AsFixedTypedVector() const { - if (IsFixedTypedVector()) { - uint8_t len = 0; - auto vtype = ToFixedTypedVectorElementType(type_, &len); - return FixedTypedVector(Indirect(), byte_width_, vtype, len); - } else { - return FixedTypedVector::EmptyFixedTypedVector(); - } - } - - Map AsMap() const { - if (type_ == FBT_MAP) { - return Map(Indirect(), byte_width_); - } else { - return Map::EmptyMap(); - } - } - - template T As() const; - - // Experimental: Mutation functions. - // These allow scalars in an already created buffer to be updated in-place. - // Since by default scalars are stored in the smallest possible space, - // the new value may not fit, in which case these functions return false. - // To avoid this, you can construct the values you intend to mutate using - // Builder::ForceMinimumBitWidth. - bool MutateInt(int64_t i) { - if (type_ == FBT_INT) { - return Mutate(data_, i, parent_width_, WidthI(i)); - } else if (type_ == FBT_INDIRECT_INT) { - return Mutate(Indirect(), i, byte_width_, WidthI(i)); - } else if (type_ == FBT_UINT) { - auto u = static_cast(i); - return Mutate(data_, u, parent_width_, WidthU(u)); - } else if (type_ == FBT_INDIRECT_UINT) { - auto u = static_cast(i); - return Mutate(Indirect(), u, byte_width_, WidthU(u)); - } else { - return false; - } - } - - bool MutateBool(bool b) { - return type_ == FBT_BOOL && Mutate(data_, b, parent_width_, BIT_WIDTH_8); - } - - bool MutateUInt(uint64_t u) { - if (type_ == FBT_UINT) { - return Mutate(data_, u, parent_width_, WidthU(u)); - } else if (type_ == FBT_INDIRECT_UINT) { - return Mutate(Indirect(), u, byte_width_, WidthU(u)); - } else if (type_ == FBT_INT) { - auto i = static_cast(u); - return Mutate(data_, i, parent_width_, WidthI(i)); - } else if (type_ == FBT_INDIRECT_INT) { - auto i = static_cast(u); - return Mutate(Indirect(), i, byte_width_, WidthI(i)); - } else { - return false; - } - } - - bool MutateFloat(float f) { - if (type_ == FBT_FLOAT) { - return MutateF(data_, f, parent_width_, BIT_WIDTH_32); - } else if (type_ == FBT_INDIRECT_FLOAT) { - return MutateF(Indirect(), f, byte_width_, BIT_WIDTH_32); - } else { - return false; - } - } - - bool MutateFloat(double d) { - if (type_ == FBT_FLOAT) { - return MutateF(data_, d, parent_width_, WidthF(d)); - } else if (type_ == FBT_INDIRECT_FLOAT) { - return MutateF(Indirect(), d, byte_width_, WidthF(d)); - } else { - return false; - } - } - - bool MutateString(const char *str, size_t len) { - auto s = AsString(); - if (s.IsTheEmptyString()) return false; - // This is very strict, could allow shorter strings, but that creates - // garbage. - if (s.length() != len) return false; - memcpy(const_cast(s.c_str()), str, len); - return true; - } - bool MutateString(const char *str) { return MutateString(str, strlen(str)); } - bool MutateString(const std::string &str) { - return MutateString(str.data(), str.length()); - } - - private: - const uint8_t *Indirect() const { - return flexbuffers::Indirect(data_, parent_width_); - } - - template - bool Mutate(const uint8_t *dest, T t, size_t byte_width, - BitWidth value_width) { - auto fits = static_cast(static_cast(1U) << value_width) <= - byte_width; - if (fits) { - t = flatbuffers::EndianScalar(t); - memcpy(const_cast(dest), &t, byte_width); - } - return fits; - } - - template - bool MutateF(const uint8_t *dest, T t, size_t byte_width, - BitWidth value_width) { - if (byte_width == sizeof(double)) - return Mutate(dest, static_cast(t), byte_width, value_width); - if (byte_width == sizeof(float)) - return Mutate(dest, static_cast(t), byte_width, value_width); - FLATBUFFERS_ASSERT(false); - return false; - } - - const uint8_t *data_; - uint8_t parent_width_; - uint8_t byte_width_; - Type type_; -}; - -// Template specialization for As(). -template<> inline bool Reference::As() const { return AsBool(); } - -template<> inline int8_t Reference::As() const { return AsInt8(); } -template<> inline int16_t Reference::As() const { return AsInt16(); } -template<> inline int32_t Reference::As() const { return AsInt32(); } -template<> inline int64_t Reference::As() const { return AsInt64(); } - -template<> inline uint8_t Reference::As() const { return AsUInt8(); } -template<> inline uint16_t Reference::As() const { - return AsUInt16(); -} -template<> inline uint32_t Reference::As() const { - return AsUInt32(); -} -template<> inline uint64_t Reference::As() const { - return AsUInt64(); -} - -template<> inline double Reference::As() const { return AsDouble(); } -template<> inline float Reference::As() const { return AsFloat(); } - -template<> inline String Reference::As() const { return AsString(); } -template<> inline std::string Reference::As() const { - return AsString().str(); -} - -template<> inline Blob Reference::As() const { return AsBlob(); } -template<> inline Vector Reference::As() const { return AsVector(); } -template<> inline TypedVector Reference::As() const { - return AsTypedVector(); -} -template<> inline FixedTypedVector Reference::As() const { - return AsFixedTypedVector(); -} -template<> inline Map Reference::As() const { return AsMap(); } - -inline uint8_t PackedType(BitWidth bit_width, Type type) { - return static_cast(bit_width | (type << 2)); -} - -inline uint8_t NullPackedType() { return PackedType(BIT_WIDTH_8, FBT_NULL); } - -// Vector accessors. -// Note: if you try to access outside of bounds, you get a Null value back -// instead. Normally this would be an assert, but since this is "dynamically -// typed" data, you may not want that (someone sends you a 2d vector and you -// wanted 3d). -// The Null converts seamlessly into a default value for any other type. -// TODO(wvo): Could introduce an #ifdef that makes this into an assert? -inline Reference Vector::operator[](size_t i) const { - auto len = size(); - if (i >= len) return Reference(nullptr, 1, NullPackedType()); - auto packed_type = (data_ + len * byte_width_)[i]; - auto elem = data_ + i * byte_width_; - return Reference(elem, byte_width_, packed_type); -} - -inline Reference TypedVector::operator[](size_t i) const { - auto len = size(); - if (i >= len) return Reference(nullptr, 1, NullPackedType()); - auto elem = data_ + i * byte_width_; - return Reference(elem, byte_width_, 1, type_); -} - -inline Reference FixedTypedVector::operator[](size_t i) const { - if (i >= len_) return Reference(nullptr, 1, NullPackedType()); - auto elem = data_ + i * byte_width_; - return Reference(elem, byte_width_, 1, type_); -} - -template int KeyCompare(const void *key, const void *elem) { - auto str_elem = reinterpret_cast( - Indirect(reinterpret_cast(elem))); - auto skey = reinterpret_cast(key); - return strcmp(skey, str_elem); -} - -inline Reference Map::operator[](const char *key) const { - auto keys = Keys(); - // We can't pass keys.byte_width_ to the comparison function, so we have - // to pick the right one ahead of time. - int (*comp)(const void *, const void *) = nullptr; - switch (keys.byte_width_) { - case 1: comp = KeyCompare; break; - case 2: comp = KeyCompare; break; - case 4: comp = KeyCompare; break; - case 8: comp = KeyCompare; break; - } - auto res = std::bsearch(key, keys.data_, keys.size(), keys.byte_width_, comp); - if (!res) return Reference(nullptr, 1, NullPackedType()); - auto i = (reinterpret_cast(res) - keys.data_) / keys.byte_width_; - return (*static_cast(this))[i]; -} - -inline Reference Map::operator[](const std::string &key) const { - return (*this)[key.c_str()]; -} - -inline Reference GetRoot(const uint8_t *buffer, size_t size) { - // See Finish() below for the serialization counterpart of this. - // The root starts at the end of the buffer, so we parse backwards from there. - auto end = buffer + size; - auto byte_width = *--end; - auto packed_type = *--end; - end -= byte_width; // The root data item. - return Reference(end, byte_width, packed_type); -} - -inline Reference GetRoot(const std::vector &buffer) { - return GetRoot(flatbuffers::vector_data(buffer), buffer.size()); -} - -// Flags that configure how the Builder behaves. -// The "Share" flags determine if the Builder automatically tries to pool -// this type. Pooling can reduce the size of serialized data if there are -// multiple maps of the same kind, at the expense of slightly slower -// serialization (the cost of lookups) and more memory use (std::set). -// By default this is on for keys, but off for strings. -// Turn keys off if you have e.g. only one map. -// Turn strings on if you expect many non-unique string values. -// Additionally, sharing key vectors can save space if you have maps with -// identical field populations. -enum BuilderFlag { - BUILDER_FLAG_NONE = 0, - BUILDER_FLAG_SHARE_KEYS = 1, - BUILDER_FLAG_SHARE_STRINGS = 2, - BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3, - BUILDER_FLAG_SHARE_KEY_VECTORS = 4, - BUILDER_FLAG_SHARE_ALL = 7, -}; - -class Builder FLATBUFFERS_FINAL_CLASS { - public: - Builder(size_t initial_size = 256, - BuilderFlag flags = BUILDER_FLAG_SHARE_KEYS) - : buf_(initial_size), - finished_(false), - flags_(flags), - force_min_bit_width_(BIT_WIDTH_8), - key_pool(KeyOffsetCompare(buf_)), - string_pool(StringOffsetCompare(buf_)) { - buf_.clear(); - } - - /// @brief Get the serialized buffer (after you call `Finish()`). - /// @return Returns a vector owned by this class. - const std::vector &GetBuffer() const { - Finished(); - return buf_; - } - - // Size of the buffer. Does not include unfinished values. - size_t GetSize() const { return buf_.size(); } - - // Reset all state so we can re-use the buffer. - void Clear() { - buf_.clear(); - stack_.clear(); - finished_ = false; - // flags_ remains as-is; - force_min_bit_width_ = BIT_WIDTH_8; - key_pool.clear(); - string_pool.clear(); - } - - // All value constructing functions below have two versions: one that - // takes a key (for placement inside a map) and one that doesn't (for inside - // vectors and elsewhere). - - void Null() { stack_.push_back(Value()); } - void Null(const char *key) { - Key(key); - Null(); - } - - void Int(int64_t i) { stack_.push_back(Value(i, FBT_INT, WidthI(i))); } - void Int(const char *key, int64_t i) { - Key(key); - Int(i); - } - - void UInt(uint64_t u) { stack_.push_back(Value(u, FBT_UINT, WidthU(u))); } - void UInt(const char *key, uint64_t u) { - Key(key); - UInt(u); - } - - void Float(float f) { stack_.push_back(Value(f)); } - void Float(const char *key, float f) { - Key(key); - Float(f); - } - - void Double(double f) { stack_.push_back(Value(f)); } - void Double(const char *key, double d) { - Key(key); - Double(d); - } - - void Bool(bool b) { stack_.push_back(Value(b)); } - void Bool(const char *key, bool b) { - Key(key); - Bool(b); - } - - void IndirectInt(int64_t i) { PushIndirect(i, FBT_INDIRECT_INT, WidthI(i)); } - void IndirectInt(const char *key, int64_t i) { - Key(key); - IndirectInt(i); - } - - void IndirectUInt(uint64_t u) { - PushIndirect(u, FBT_INDIRECT_UINT, WidthU(u)); - } - void IndirectUInt(const char *key, uint64_t u) { - Key(key); - IndirectUInt(u); - } - - void IndirectFloat(float f) { - PushIndirect(f, FBT_INDIRECT_FLOAT, BIT_WIDTH_32); - } - void IndirectFloat(const char *key, float f) { - Key(key); - IndirectFloat(f); - } - - void IndirectDouble(double f) { - PushIndirect(f, FBT_INDIRECT_FLOAT, WidthF(f)); - } - void IndirectDouble(const char *key, double d) { - Key(key); - IndirectDouble(d); - } - - size_t Key(const char *str, size_t len) { - auto sloc = buf_.size(); - WriteBytes(str, len + 1); - if (flags_ & BUILDER_FLAG_SHARE_KEYS) { - auto it = key_pool.find(sloc); - if (it != key_pool.end()) { - // Already in the buffer. Remove key we just serialized, and use - // existing offset instead. - buf_.resize(sloc); - sloc = *it; - } else { - key_pool.insert(sloc); - } - } - stack_.push_back(Value(static_cast(sloc), FBT_KEY, BIT_WIDTH_8)); - return sloc; - } - - size_t Key(const char *str) { return Key(str, strlen(str)); } - size_t Key(const std::string &str) { return Key(str.c_str(), str.size()); } - - size_t String(const char *str, size_t len) { - auto reset_to = buf_.size(); - auto sloc = CreateBlob(str, len, 1, FBT_STRING); - if (flags_ & BUILDER_FLAG_SHARE_STRINGS) { - StringOffset so(sloc, len); - auto it = string_pool.find(so); - if (it != string_pool.end()) { - // Already in the buffer. Remove string we just serialized, and use - // existing offset instead. - buf_.resize(reset_to); - sloc = it->first; - stack_.back().u_ = sloc; - } else { - string_pool.insert(so); - } - } - return sloc; - } - size_t String(const char *str) { return String(str, strlen(str)); } - size_t String(const std::string &str) { - return String(str.c_str(), str.size()); - } - void String(const flexbuffers::String &str) { - String(str.c_str(), str.length()); - } - - void String(const char *key, const char *str) { - Key(key); - String(str); - } - void String(const char *key, const std::string &str) { - Key(key); - String(str); - } - void String(const char *key, const flexbuffers::String &str) { - Key(key); - String(str); - } - - size_t Blob(const void *data, size_t len) { - return CreateBlob(data, len, 0, FBT_BLOB); - } - size_t Blob(const std::vector &v) { - return CreateBlob(flatbuffers::vector_data(v), v.size(), 0, FBT_BLOB); - } - - // TODO(wvo): support all the FlexBuffer types (like flexbuffers::String), - // e.g. Vector etc. Also in overloaded versions. - // Also some FlatBuffers types? - - size_t StartVector() { return stack_.size(); } - size_t StartVector(const char *key) { - Key(key); - return stack_.size(); - } - size_t StartMap() { return stack_.size(); } - size_t StartMap(const char *key) { - Key(key); - return stack_.size(); - } - - // TODO(wvo): allow this to specify an aligment greater than the natural - // alignment. - size_t EndVector(size_t start, bool typed, bool fixed) { - auto vec = CreateVector(start, stack_.size() - start, 1, typed, fixed); - // Remove temp elements and return vector. - stack_.resize(start); - stack_.push_back(vec); - return static_cast(vec.u_); - } - - size_t EndMap(size_t start) { - // We should have interleaved keys and values on the stack. - // Make sure it is an even number: - auto len = stack_.size() - start; - FLATBUFFERS_ASSERT(!(len & 1)); - len /= 2; - // Make sure keys are all strings: - for (auto key = start; key < stack_.size(); key += 2) { - FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY); - } - // Now sort values, so later we can do a binary search lookup. - // We want to sort 2 array elements at a time. - struct TwoValue { - Value key; - Value val; - }; - // TODO(wvo): strict aliasing? - // TODO(wvo): allow the caller to indicate the data is already sorted - // for maximum efficiency? With an assert to check sortedness to make sure - // we're not breaking binary search. - // Or, we can track if the map is sorted as keys are added which would be - // be quite cheap (cheaper than checking it here), so we can skip this - // step automatically when appliccable, and encourage people to write in - // sorted fashion. - // std::sort is typically already a lot faster on sorted data though. - auto dict = - reinterpret_cast(flatbuffers::vector_data(stack_) + start); - std::sort(dict, dict + len, - [&](const TwoValue &a, const TwoValue &b) -> bool { - auto as = reinterpret_cast( - flatbuffers::vector_data(buf_) + a.key.u_); - auto bs = reinterpret_cast( - flatbuffers::vector_data(buf_) + b.key.u_); - auto comp = strcmp(as, bs); - // If this assertion hits, you've added two keys with the same - // value to this map. - // TODO: Have to check for pointer equality, as some sort - // implementation apparently call this function with the same - // element?? Why? - FLATBUFFERS_ASSERT(comp || &a == &b); - return comp < 0; - }); - // First create a vector out of all keys. - // TODO(wvo): if kBuilderFlagShareKeyVectors is true, see if we can share - // the first vector. - auto keys = CreateVector(start, len, 2, true, false); - auto vec = CreateVector(start + 1, len, 2, false, false, &keys); - // Remove temp elements and return map. - stack_.resize(start); - stack_.push_back(vec); - return static_cast(vec.u_); - } - - template size_t Vector(F f) { - auto start = StartVector(); - f(); - return EndVector(start, false, false); - } - template size_t Vector(F f, T &state) { - auto start = StartVector(); - f(state); - return EndVector(start, false, false); - } - template size_t Vector(const char *key, F f) { - auto start = StartVector(key); - f(); - return EndVector(start, false, false); - } - template - size_t Vector(const char *key, F f, T &state) { - auto start = StartVector(key); - f(state); - return EndVector(start, false, false); - } - - template void Vector(const T *elems, size_t len) { - if (flatbuffers::is_scalar::value) { - // This path should be a lot quicker and use less space. - ScalarVector(elems, len, false); - } else { - auto start = StartVector(); - for (size_t i = 0; i < len; i++) Add(elems[i]); - EndVector(start, false, false); - } - } - template - void Vector(const char *key, const T *elems, size_t len) { - Key(key); - Vector(elems, len); - } - template void Vector(const std::vector &vec) { - Vector(flatbuffers::vector_data(vec), vec.size()); - } - - template size_t TypedVector(F f) { - auto start = StartVector(); - f(); - return EndVector(start, true, false); - } - template size_t TypedVector(F f, T &state) { - auto start = StartVector(); - f(state); - return EndVector(start, true, false); - } - template size_t TypedVector(const char *key, F f) { - auto start = StartVector(key); - f(); - return EndVector(start, true, false); - } - template - size_t TypedVector(const char *key, F f, T &state) { - auto start = StartVector(key); - f(state); - return EndVector(start, true, false); - } - - template size_t FixedTypedVector(const T *elems, size_t len) { - // We only support a few fixed vector lengths. Anything bigger use a - // regular typed vector. - FLATBUFFERS_ASSERT(len >= 2 && len <= 4); - // And only scalar values. - static_assert(flatbuffers::is_scalar::value, "Unrelated types"); - return ScalarVector(elems, len, true); - } - - template - size_t FixedTypedVector(const char *key, const T *elems, size_t len) { - Key(key); - return FixedTypedVector(elems, len); - } - - template size_t Map(F f) { - auto start = StartMap(); - f(); - return EndMap(start); - } - template size_t Map(F f, T &state) { - auto start = StartMap(); - f(state); - return EndMap(start); - } - template size_t Map(const char *key, F f) { - auto start = StartMap(key); - f(); - return EndMap(start); - } - template size_t Map(const char *key, F f, T &state) { - auto start = StartMap(key); - f(state); - return EndMap(start); - } - template void Map(const std::map &map) { - auto start = StartMap(); - for (auto it = map.begin(); it != map.end(); ++it) - Add(it->first.c_str(), it->second); - EndMap(start); - } - - // If you wish to share a value explicitly (a value not shared automatically - // through one of the BUILDER_FLAG_SHARE_* flags) you can do so with these - // functions. Or if you wish to turn those flags off for performance reasons - // and still do some explicit sharing. For example: - // builder.IndirectDouble(M_PI); - // auto id = builder.LastValue(); // Remember where we stored it. - // .. more code goes here .. - // builder.ReuseValue(id); // Refers to same double by offset. - // LastValue works regardless of whether the value has a key or not. - // Works on any data type. - struct Value; - Value LastValue() { return stack_.back(); } - void ReuseValue(Value v) { stack_.push_back(v); } - void ReuseValue(const char *key, Value v) { - Key(key); - ReuseValue(v); - } - - // Overloaded Add that tries to call the correct function above. - void Add(int8_t i) { Int(i); } - void Add(int16_t i) { Int(i); } - void Add(int32_t i) { Int(i); } - void Add(int64_t i) { Int(i); } - void Add(uint8_t u) { UInt(u); } - void Add(uint16_t u) { UInt(u); } - void Add(uint32_t u) { UInt(u); } - void Add(uint64_t u) { UInt(u); } - void Add(float f) { Float(f); } - void Add(double d) { Double(d); } - void Add(bool b) { Bool(b); } - void Add(const char *str) { String(str); } - void Add(const std::string &str) { String(str); } - void Add(const flexbuffers::String &str) { String(str); } - - template void Add(const std::vector &vec) { Vector(vec); } - - template void Add(const char *key, const T &t) { - Key(key); - Add(t); - } - - template void Add(const std::map &map) { - Map(map); - } - - template void operator+=(const T &t) { Add(t); } - - // This function is useful in combination with the Mutate* functions above. - // It forces elements of vectors and maps to have a minimum size, such that - // they can later be updated without failing. - // Call with no arguments to reset. - void ForceMinimumBitWidth(BitWidth bw = BIT_WIDTH_8) { - force_min_bit_width_ = bw; - } - - void Finish() { - // If you hit this assert, you likely have objects that were never included - // in a parent. You need to have exactly one root to finish a buffer. - // Check your Start/End calls are matched, and all objects are inside - // some other object. - FLATBUFFERS_ASSERT(stack_.size() == 1); - - // Write root value. - auto byte_width = Align(stack_[0].ElemWidth(buf_.size(), 0)); - WriteAny(stack_[0], byte_width); - // Write root type. - Write(stack_[0].StoredPackedType(), 1); - // Write root size. Normally determined by parent, but root has no parent :) - Write(byte_width, 1); - - finished_ = true; - } - - private: - void Finished() const { - // If you get this assert, you're attempting to get access a buffer - // which hasn't been finished yet. Be sure to call - // Builder::Finish with your root object. - FLATBUFFERS_ASSERT(finished_); - } - - // Align to prepare for writing a scalar with a certain size. - uint8_t Align(BitWidth alignment) { - auto byte_width = 1U << alignment; - buf_.insert(buf_.end(), flatbuffers::PaddingBytes(buf_.size(), byte_width), - 0); - return static_cast(byte_width); - } - - void WriteBytes(const void *val, size_t size) { - buf_.insert(buf_.end(), reinterpret_cast(val), - reinterpret_cast(val) + size); - } - - template void Write(T val, size_t byte_width) { - FLATBUFFERS_ASSERT(sizeof(T) >= byte_width); - val = flatbuffers::EndianScalar(val); - WriteBytes(&val, byte_width); - } - - void WriteDouble(double f, uint8_t byte_width) { - switch (byte_width) { - case 8: Write(f, byte_width); break; - case 4: Write(static_cast(f), byte_width); break; - // case 2: Write(static_cast(f), byte_width); break; - // case 1: Write(static_cast(f), byte_width); break; - default: FLATBUFFERS_ASSERT(0); - } - } - - void WriteOffset(uint64_t o, uint8_t byte_width) { - auto reloff = buf_.size() - o; - FLATBUFFERS_ASSERT(byte_width == 8 || reloff < 1ULL << (byte_width * 8)); - Write(reloff, byte_width); - } - - template void PushIndirect(T val, Type type, BitWidth bit_width) { - auto byte_width = Align(bit_width); - auto iloc = buf_.size(); - Write(val, byte_width); - stack_.push_back(Value(static_cast(iloc), type, bit_width)); - } - - static BitWidth WidthB(size_t byte_width) { - switch (byte_width) { - case 1: return BIT_WIDTH_8; - case 2: return BIT_WIDTH_16; - case 4: return BIT_WIDTH_32; - case 8: return BIT_WIDTH_64; - default: FLATBUFFERS_ASSERT(false); return BIT_WIDTH_64; - } - } - - template static Type GetScalarType() { - static_assert(flatbuffers::is_scalar::value, "Unrelated types"); - return flatbuffers::is_floating_point::value - ? FBT_FLOAT - : flatbuffers::is_same::value - ? FBT_BOOL - : (flatbuffers::is_unsigned::value ? FBT_UINT - : FBT_INT); - } - - public: - // This was really intended to be private, except for LastValue/ReuseValue. - struct Value { - union { - int64_t i_; - uint64_t u_; - double f_; - }; - - Type type_; - - // For scalars: of itself, for vector: of its elements, for string: length. - BitWidth min_bit_width_; - - Value() : i_(0), type_(FBT_NULL), min_bit_width_(BIT_WIDTH_8) {} - - Value(bool b) - : u_(static_cast(b)), - type_(FBT_BOOL), - min_bit_width_(BIT_WIDTH_8) {} - - Value(int64_t i, Type t, BitWidth bw) - : i_(i), type_(t), min_bit_width_(bw) {} - Value(uint64_t u, Type t, BitWidth bw) - : u_(u), type_(t), min_bit_width_(bw) {} - - Value(float f) : f_(f), type_(FBT_FLOAT), min_bit_width_(BIT_WIDTH_32) {} - Value(double f) : f_(f), type_(FBT_FLOAT), min_bit_width_(WidthF(f)) {} - - uint8_t StoredPackedType(BitWidth parent_bit_width_ = BIT_WIDTH_8) const { - return PackedType(StoredWidth(parent_bit_width_), type_); - } - - BitWidth ElemWidth(size_t buf_size, size_t elem_index) const { - if (IsInline(type_)) { - return min_bit_width_; - } else { - // We have an absolute offset, but want to store a relative offset - // elem_index elements beyond the current buffer end. Since whether - // the relative offset fits in a certain byte_width depends on - // the size of the elements before it (and their alignment), we have - // to test for each size in turn. - for (size_t byte_width = 1; - byte_width <= sizeof(flatbuffers::largest_scalar_t); - byte_width *= 2) { - // Where are we going to write this offset? - auto offset_loc = buf_size + - flatbuffers::PaddingBytes(buf_size, byte_width) + - elem_index * byte_width; - // Compute relative offset. - auto offset = offset_loc - u_; - // Does it fit? - auto bit_width = WidthU(offset); - if (static_cast(static_cast(1U) << bit_width) == - byte_width) - return bit_width; - } - FLATBUFFERS_ASSERT(false); // Must match one of the sizes above. - return BIT_WIDTH_64; - } - } - - BitWidth StoredWidth(BitWidth parent_bit_width_ = BIT_WIDTH_8) const { - if (IsInline(type_)) { - return (std::max)(min_bit_width_, parent_bit_width_); - } else { - return min_bit_width_; - } - } - }; - - private: - void WriteAny(const Value &val, uint8_t byte_width) { - switch (val.type_) { - case FBT_NULL: - case FBT_INT: Write(val.i_, byte_width); break; - case FBT_BOOL: - case FBT_UINT: Write(val.u_, byte_width); break; - case FBT_FLOAT: WriteDouble(val.f_, byte_width); break; - default: WriteOffset(val.u_, byte_width); break; - } - } - - size_t CreateBlob(const void *data, size_t len, size_t trailing, Type type) { - auto bit_width = WidthU(len); - auto byte_width = Align(bit_width); - Write(len, byte_width); - auto sloc = buf_.size(); - WriteBytes(data, len + trailing); - stack_.push_back(Value(static_cast(sloc), type, bit_width)); - return sloc; - } - - template - size_t ScalarVector(const T *elems, size_t len, bool fixed) { - auto vector_type = GetScalarType(); - auto byte_width = sizeof(T); - auto bit_width = WidthB(byte_width); - // If you get this assert, you're trying to write a vector with a size - // field that is bigger than the scalars you're trying to write (e.g. a - // byte vector > 255 elements). For such types, write a "blob" instead. - // TODO: instead of asserting, could write vector with larger elements - // instead, though that would be wasteful. - FLATBUFFERS_ASSERT(WidthU(len) <= bit_width); - Align(bit_width); - if (!fixed) Write(len, byte_width); - auto vloc = buf_.size(); - for (size_t i = 0; i < len; i++) Write(elems[i], byte_width); - stack_.push_back(Value(static_cast(vloc), - ToTypedVector(vector_type, fixed ? len : 0), - bit_width)); - return vloc; - } - - Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed, - bool fixed, const Value *keys = nullptr) { - FLATBUFFERS_ASSERT( - !fixed || - typed); // typed=false, fixed=true combination is not supported. - // Figure out smallest bit width we can store this vector with. - auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len)); - auto prefix_elems = 1; - if (keys) { - // If this vector is part of a map, we will pre-fix an offset to the keys - // to this vector. - bit_width = (std::max)(bit_width, keys->ElemWidth(buf_.size(), 0)); - prefix_elems += 2; - } - Type vector_type = FBT_KEY; - // Check bit widths and types for all elements. - for (size_t i = start; i < stack_.size(); i += step) { - auto elem_width = - stack_[i].ElemWidth(buf_.size(), i - start + prefix_elems); - bit_width = (std::max)(bit_width, elem_width); - if (typed) { - if (i == start) { - vector_type = stack_[i].type_; - } else { - // If you get this assert, you are writing a typed vector with - // elements that are not all the same type. - FLATBUFFERS_ASSERT(vector_type == stack_[i].type_); - } - } - } - // If you get this assert, your fixed types are not one of: - // Int / UInt / Float / Key. - FLATBUFFERS_ASSERT(!fixed || IsTypedVectorElementType(vector_type)); - auto byte_width = Align(bit_width); - // Write vector. First the keys width/offset if available, and size. - if (keys) { - WriteOffset(keys->u_, byte_width); - Write(1ULL << keys->min_bit_width_, byte_width); - } - if (!fixed) Write(vec_len, byte_width); - // Then the actual data. - auto vloc = buf_.size(); - for (size_t i = start; i < stack_.size(); i += step) { - WriteAny(stack_[i], byte_width); - } - // Then the types. - if (!typed) { - for (size_t i = start; i < stack_.size(); i += step) { - buf_.push_back(stack_[i].StoredPackedType(bit_width)); - } - } - return Value(static_cast(vloc), - keys ? FBT_MAP - : (typed ? ToTypedVector(vector_type, fixed ? vec_len : 0) - : FBT_VECTOR), - bit_width); - } - - // You shouldn't really be copying instances of this class. - Builder(const Builder &); - Builder &operator=(const Builder &); - - std::vector buf_; - std::vector stack_; - - bool finished_; - - BuilderFlag flags_; - - BitWidth force_min_bit_width_; - - struct KeyOffsetCompare { - explicit KeyOffsetCompare(const std::vector &buf) : buf_(&buf) {} - bool operator()(size_t a, size_t b) const { - auto stra = - reinterpret_cast(flatbuffers::vector_data(*buf_) + a); - auto strb = - reinterpret_cast(flatbuffers::vector_data(*buf_) + b); - return strcmp(stra, strb) < 0; - } - const std::vector *buf_; - }; - - typedef std::pair StringOffset; - struct StringOffsetCompare { - explicit StringOffsetCompare(const std::vector &buf) - : buf_(&buf) {} - bool operator()(const StringOffset &a, const StringOffset &b) const { - auto stra = reinterpret_cast( - flatbuffers::vector_data(*buf_) + a.first); - auto strb = reinterpret_cast( - flatbuffers::vector_data(*buf_) + b.first); - return strncmp(stra, strb, (std::min)(a.second, b.second) + 1) < 0; - } - const std::vector *buf_; - }; - - typedef std::set KeyOffsetMap; - typedef std::set StringOffsetMap; - - KeyOffsetMap key_pool; - StringOffsetMap string_pool; -}; - -} // namespace flexbuffers - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif - -#endif // FLATBUFFERS_FLEXBUFFERS_H_ diff --git a/daemon/src/External/include/flatbuffers/grpc.h b/daemon/src/External/include/flatbuffers/grpc.h deleted file mode 100644 index bd24c501..00000000 --- a/daemon/src/External/include/flatbuffers/grpc.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_GRPC_H_ -#define FLATBUFFERS_GRPC_H_ - -// Helper functionality to glue FlatBuffers and GRPC. - -#include "flatbuffers/flatbuffers.h" -#include "grpc++/support/byte_buffer.h" -#include "grpc/byte_buffer_reader.h" - -namespace flatbuffers { -namespace grpc { - -// Message is a typed wrapper around a buffer that manages the underlying -// `grpc_slice` and also provides flatbuffers-specific helpers such as `Verify` -// and `GetRoot`. Since it is backed by a `grpc_slice`, the underlying buffer -// is refcounted and ownership is be managed automatically. -template class Message { - public: - Message() : slice_(grpc_empty_slice()) {} - - Message(grpc_slice slice, bool add_ref) - : slice_(add_ref ? grpc_slice_ref(slice) : slice) {} - - Message &operator=(const Message &other) = delete; - - Message(Message &&other) : slice_(other.slice_) { - other.slice_ = grpc_empty_slice(); - } - - Message(const Message &other) = delete; - - Message &operator=(Message &&other) { - grpc_slice_unref(slice_); - slice_ = other.slice_; - other.slice_ = grpc_empty_slice(); - return *this; - } - - ~Message() { grpc_slice_unref(slice_); } - - const uint8_t *mutable_data() const { return GRPC_SLICE_START_PTR(slice_); } - - const uint8_t *data() const { return GRPC_SLICE_START_PTR(slice_); } - - size_t size() const { return GRPC_SLICE_LENGTH(slice_); } - - bool Verify() const { - Verifier verifier(data(), size()); - return verifier.VerifyBuffer(nullptr); - } - - T *GetMutableRoot() { return flatbuffers::GetMutableRoot(mutable_data()); } - - const T *GetRoot() const { return flatbuffers::GetRoot(data()); } - - // This is only intended for serializer use, or if you know what you're doing - const grpc_slice &BorrowSlice() const { return slice_; } - - private: - grpc_slice slice_; -}; - -class MessageBuilder; - -// SliceAllocator is a gRPC-specific allocator that uses the `grpc_slice` -// refcounted slices to manage memory ownership. This makes it easy and -// efficient to transfer buffers to gRPC. -class SliceAllocator : public Allocator { - public: - SliceAllocator() : slice_(grpc_empty_slice()) {} - - SliceAllocator(const SliceAllocator &other) = delete; - SliceAllocator &operator=(const SliceAllocator &other) = delete; - - SliceAllocator(SliceAllocator &&other) : slice_(grpc_empty_slice()) { - // default-construct and swap idiom - swap(other); - } - - SliceAllocator &operator=(SliceAllocator &&other) { - // move-construct and swap idiom - SliceAllocator temp(std::move(other)); - swap(temp); - return *this; - } - - void swap(SliceAllocator &other) { - using std::swap; - swap(slice_, other.slice_); - } - - virtual ~SliceAllocator() { grpc_slice_unref(slice_); } - - virtual uint8_t *allocate(size_t size) override { - FLATBUFFERS_ASSERT(GRPC_SLICE_IS_EMPTY(slice_)); - slice_ = grpc_slice_malloc(size); - return GRPC_SLICE_START_PTR(slice_); - } - - virtual void deallocate(uint8_t *p, size_t size) override { - FLATBUFFERS_ASSERT(p == GRPC_SLICE_START_PTR(slice_)); - FLATBUFFERS_ASSERT(size == GRPC_SLICE_LENGTH(slice_)); - grpc_slice_unref(slice_); - slice_ = grpc_empty_slice(); - } - - virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size, - size_t new_size, size_t in_use_back, - size_t in_use_front) override { - FLATBUFFERS_ASSERT(old_p == GRPC_SLICE_START_PTR(slice_)); - FLATBUFFERS_ASSERT(old_size == GRPC_SLICE_LENGTH(slice_)); - FLATBUFFERS_ASSERT(new_size > old_size); - grpc_slice old_slice = slice_; - grpc_slice new_slice = grpc_slice_malloc(new_size); - uint8_t *new_p = GRPC_SLICE_START_PTR(new_slice); - memcpy_downward(old_p, old_size, new_p, new_size, in_use_back, - in_use_front); - slice_ = new_slice; - grpc_slice_unref(old_slice); - return new_p; - } - - private: - grpc_slice &get_slice(uint8_t *p, size_t size) { - FLATBUFFERS_ASSERT(p == GRPC_SLICE_START_PTR(slice_)); - FLATBUFFERS_ASSERT(size == GRPC_SLICE_LENGTH(slice_)); - return slice_; - } - - grpc_slice slice_; - - friend class MessageBuilder; -}; - -// SliceAllocatorMember is a hack to ensure that the MessageBuilder's -// slice_allocator_ member is constructed before the FlatBufferBuilder, since -// the allocator is used in the FlatBufferBuilder ctor. -namespace detail { -struct SliceAllocatorMember { - SliceAllocator slice_allocator_; -}; -} // namespace detail - -// MessageBuilder is a gRPC-specific FlatBufferBuilder that uses SliceAllocator -// to allocate gRPC buffers. -class MessageBuilder : private detail::SliceAllocatorMember, - public FlatBufferBuilder { - public: - explicit MessageBuilder(uoffset_t initial_size = 1024) - : FlatBufferBuilder(initial_size, &slice_allocator_, false) {} - - MessageBuilder(const MessageBuilder &other) = delete; - MessageBuilder &operator=(const MessageBuilder &other) = delete; - - MessageBuilder(MessageBuilder &&other) - : FlatBufferBuilder(1024, &slice_allocator_, false) { - // Default construct and swap idiom. - Swap(other); - } - - /// Create a MessageBuilder from a FlatBufferBuilder. - explicit MessageBuilder(FlatBufferBuilder &&src, - void (*dealloc)(void *, - size_t) = &DefaultAllocator::dealloc) - : FlatBufferBuilder(1024, &slice_allocator_, false) { - src.Swap(*this); - src.SwapBufAllocator(*this); - if (buf_.capacity()) { - uint8_t *buf = buf_.scratch_data(); // pointer to memory - size_t capacity = buf_.capacity(); // size of memory - slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc); - } else { - slice_allocator_.slice_ = grpc_empty_slice(); - } - } - - /// Move-assign a FlatBufferBuilder to a MessageBuilder. - /// Only FlatBufferBuilder with default allocator (basically, nullptr) is - /// supported. - MessageBuilder &operator=(FlatBufferBuilder &&src) { - // Move construct a temporary and swap - MessageBuilder temp(std::move(src)); - Swap(temp); - return *this; - } - - MessageBuilder &operator=(MessageBuilder &&other) { - // Move construct a temporary and swap - MessageBuilder temp(std::move(other)); - Swap(temp); - return *this; - } - - void Swap(MessageBuilder &other) { - slice_allocator_.swap(other.slice_allocator_); - FlatBufferBuilder::Swap(other); - // After swapping the FlatBufferBuilder, we swap back the allocator, which - // restores the original allocator back in place. This is necessary because - // MessageBuilder's allocator is its own member (SliceAllocatorMember). The - // allocator passed to FlatBufferBuilder::vector_downward must point to this - // member. - buf_.swap_allocator(other.buf_); - } - - // Releases the ownership of the buffer pointer. - // Returns the size, offset, and the original grpc_slice that - // allocated the buffer. Also see grpc_slice_unref(). - uint8_t *ReleaseRaw(size_t &size, size_t &offset, grpc_slice &slice) { - uint8_t *buf = FlatBufferBuilder::ReleaseRaw(size, offset); - slice = slice_allocator_.slice_; - slice_allocator_.slice_ = grpc_empty_slice(); - return buf; - } - - ~MessageBuilder() {} - - // GetMessage extracts the subslice of the buffer corresponding to the - // flatbuffers-encoded region and wraps it in a `Message` to handle buffer - // ownership. - template Message GetMessage() { - auto buf_data = buf_.scratch_data(); // pointer to memory - auto buf_size = buf_.capacity(); // size of memory - auto msg_data = buf_.data(); // pointer to msg - auto msg_size = buf_.size(); // size of msg - // Do some sanity checks on data/size - FLATBUFFERS_ASSERT(msg_data); - FLATBUFFERS_ASSERT(msg_size); - FLATBUFFERS_ASSERT(msg_data >= buf_data); - FLATBUFFERS_ASSERT(msg_data + msg_size <= buf_data + buf_size); - // Calculate offsets from the buffer start - auto begin = msg_data - buf_data; - auto end = begin + msg_size; - // Get the slice we are working with (no refcount change) - grpc_slice slice = slice_allocator_.get_slice(buf_data, buf_size); - // Extract a subslice of the existing slice (increment refcount) - grpc_slice subslice = grpc_slice_sub(slice, begin, end); - // Wrap the subslice in a `Message`, but don't increment refcount - Message msg(subslice, false); - return msg; - } - - template Message ReleaseMessage() { - Message msg = GetMessage(); - Reset(); - return msg; - } - - private: - // SliceAllocator slice_allocator_; // part of SliceAllocatorMember -}; - -} // namespace grpc -} // namespace flatbuffers - -namespace grpc { - -template class SerializationTraits> { - public: - static grpc::Status Serialize(const flatbuffers::grpc::Message &msg, - grpc_byte_buffer **buffer, bool *own_buffer) { - // We are passed in a `Message`, which is a wrapper around a - // `grpc_slice`. We extract it here using `BorrowSlice()`. The const cast - // is necessary because the `grpc_raw_byte_buffer_create` func expects - // non-const slices in order to increment their refcounts. - grpc_slice *slice = const_cast(&msg.BorrowSlice()); - // Now use `grpc_raw_byte_buffer_create` to package the single slice into a - // `grpc_byte_buffer`, incrementing the refcount in the process. - *buffer = grpc_raw_byte_buffer_create(slice, 1); - *own_buffer = true; - return grpc::Status::OK; - } - - // Deserialize by pulling the - static grpc::Status Deserialize(grpc_byte_buffer *buffer, - flatbuffers::grpc::Message *msg) { - if (!buffer) { - return ::grpc::Status(::grpc::StatusCode::INTERNAL, "No payload"); - } - // Check if this is a single uncompressed slice. - if ((buffer->type == GRPC_BB_RAW) && - (buffer->data.raw.compression == GRPC_COMPRESS_NONE) && - (buffer->data.raw.slice_buffer.count == 1)) { - // If it is, then we can reference the `grpc_slice` directly. - grpc_slice slice = buffer->data.raw.slice_buffer.slices[0]; - // We wrap a `Message` around the slice, incrementing the refcount. - *msg = flatbuffers::grpc::Message(slice, true); - } else { - // Otherwise, we need to use `grpc_byte_buffer_reader_readall` to read - // `buffer` into a single contiguous `grpc_slice`. The gRPC reader gives - // us back a new slice with the refcount already incremented. - grpc_byte_buffer_reader reader; - grpc_byte_buffer_reader_init(&reader, buffer); - grpc_slice slice = grpc_byte_buffer_reader_readall(&reader); - grpc_byte_buffer_reader_destroy(&reader); - // We wrap a `Message` around the slice, but don't increment refcount - *msg = flatbuffers::grpc::Message(slice, false); - } - grpc_byte_buffer_destroy(buffer); -#if FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION - return ::grpc::Status::OK; -#else - if (msg->Verify()) { - return ::grpc::Status::OK; - } else { - return ::grpc::Status(::grpc::StatusCode::INTERNAL, - "Message verification failed"); - } -#endif - } -}; - -} // namespace grpc - -#endif // FLATBUFFERS_GRPC_H_ diff --git a/daemon/src/External/include/flatbuffers/hash.h b/daemon/src/External/include/flatbuffers/hash.h deleted file mode 100644 index aebf0713..00000000 --- a/daemon/src/External/include/flatbuffers/hash.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2015 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_HASH_H_ -#define FLATBUFFERS_HASH_H_ - -#include -#include - -#include "flatbuffers/flatbuffers.h" - -namespace flatbuffers { - -template struct FnvTraits { - static const T kFnvPrime; - static const T kOffsetBasis; -}; - -template<> struct FnvTraits { - static const uint32_t kFnvPrime = 0x01000193; - static const uint32_t kOffsetBasis = 0x811C9DC5; -}; - -template<> struct FnvTraits { - static const uint64_t kFnvPrime = 0x00000100000001b3ULL; - static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL; -}; - -template T HashFnv1(const char *input) { - T hash = FnvTraits::kOffsetBasis; - for (const char *c = input; *c; ++c) { - hash *= FnvTraits::kFnvPrime; - hash ^= static_cast(*c); - } - return hash; -} - -template T HashFnv1a(const char *input) { - T hash = FnvTraits::kOffsetBasis; - for (const char *c = input; *c; ++c) { - hash ^= static_cast(*c); - hash *= FnvTraits::kFnvPrime; - } - return hash; -} - -template<> inline uint16_t HashFnv1(const char *input) { - uint32_t hash = HashFnv1(input); - return (hash >> 16) ^ (hash & 0xffff); -} - -template<> inline uint16_t HashFnv1a(const char *input) { - uint32_t hash = HashFnv1a(input); - return (hash >> 16) ^ (hash & 0xffff); -} - -template struct NamedHashFunction { - const char *name; - - typedef T (*HashFunction)(const char *); - HashFunction function; -}; - -const NamedHashFunction kHashFunctions16[] = { - { "fnv1_16", HashFnv1 }, - { "fnv1a_16", HashFnv1a }, -}; - -const NamedHashFunction kHashFunctions32[] = { - { "fnv1_32", HashFnv1 }, - { "fnv1a_32", HashFnv1a }, -}; - -const NamedHashFunction kHashFunctions64[] = { - { "fnv1_64", HashFnv1 }, - { "fnv1a_64", HashFnv1a }, -}; - -inline NamedHashFunction::HashFunction FindHashFunction16( - const char *name) { - std::size_t size = sizeof(kHashFunctions16) / sizeof(kHashFunctions16[0]); - for (std::size_t i = 0; i < size; ++i) { - if (std::strcmp(name, kHashFunctions16[i].name) == 0) { - return kHashFunctions16[i].function; - } - } - return nullptr; -} - -inline NamedHashFunction::HashFunction FindHashFunction32( - const char *name) { - std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]); - for (std::size_t i = 0; i < size; ++i) { - if (std::strcmp(name, kHashFunctions32[i].name) == 0) { - return kHashFunctions32[i].function; - } - } - return nullptr; -} - -inline NamedHashFunction::HashFunction FindHashFunction64( - const char *name) { - std::size_t size = sizeof(kHashFunctions64) / sizeof(kHashFunctions64[0]); - for (std::size_t i = 0; i < size; ++i) { - if (std::strcmp(name, kHashFunctions64[i].name) == 0) { - return kHashFunctions64[i].function; - } - } - return nullptr; -} - -} // namespace flatbuffers - -#endif // FLATBUFFERS_HASH_H_ diff --git a/daemon/src/External/include/flatbuffers/idl.h b/daemon/src/External/include/flatbuffers/idl.h deleted file mode 100644 index 8c02f282..00000000 --- a/daemon/src/External/include/flatbuffers/idl.h +++ /dev/null @@ -1,1136 +0,0 @@ -/* - * Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_IDL_H_ -#define FLATBUFFERS_IDL_H_ - -#include -#include -#include - -#include "flatbuffers/base.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/flexbuffers.h" -#include "flatbuffers/hash.h" -#include "flatbuffers/reflection.h" - -#if !defined(FLATBUFFERS_CPP98_STL) -# include -#endif // !defined(FLATBUFFERS_CPP98_STL) - -// This file defines the data types representing a parsed IDL (Interface -// Definition Language) / schema file. - -// Limits maximum depth of nested objects. -// Prevents stack overflow while parse flatbuffers or json. -#if !defined(FLATBUFFERS_MAX_PARSING_DEPTH) -# define FLATBUFFERS_MAX_PARSING_DEPTH 64 -#endif - -namespace flatbuffers { - -// The order of these matters for Is*() functions below. -// Additionally, Parser::ParseType assumes bool..string is a contiguous range -// of type tokens. -// clang-format off -#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \ - TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) \ - TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) /* begin scalar/int */ \ - TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool, Boolean, Bool) \ - TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8, Byte, Int8) \ - TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) \ - TD(SHORT, "short", int16_t, short, int16, short, int16, i16, Short, Int16) \ - TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16, UShort, UInt16) \ - TD(INT, "int", int32_t, int, int32, int, int32, i32, Int, Int32) \ - TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32, UInt, UInt32) \ - TD(LONG, "long", int64_t, long, int64, long, int64, i64, Long, Int64) \ - TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64, ULong, UInt64) /* end int */ \ - TD(FLOAT, "float", float, float, float32, float, float32, f32, Float, Float32) /* begin float */ \ - TD(DOUBLE, "double", double, double, float64, double, float64, f64, Double, Double) /* end float/scalar */ -#define FLATBUFFERS_GEN_TYPES_POINTER(TD) \ - TD(STRING, "string", Offset, int, int, StringOffset, int, unused, Int, Offset) \ - TD(VECTOR, "", Offset, int, int, VectorOffset, int, unused, Int, Offset) \ - TD(STRUCT, "", Offset, int, int, int, int, unused, Int, Offset) \ - TD(UNION, "", Offset, int, int, int, int, unused, Int, Offset) -#define FLATBUFFERS_GEN_TYPE_ARRAY(TD) \ - TD(ARRAY, "", int, int, int, int, int, unused, Int, Offset) -// The fields are: -// - enum -// - FlatBuffers schema type. -// - C++ type. -// - Java type. -// - Go type. -// - C# / .Net type. -// - Python type. -// - Rust type. -// - Kotlin type. - -// using these macros, we can now write code dealing with types just once, e.g. - -/* -switch (type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ - RTYPE, KTYPE) \ - case BASE_TYPE_ ## ENUM: \ - // do something specific to CTYPE here - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD -} -*/ - -// If not all FLATBUFFERS_GEN_() arguments are necessary for implementation -// of FLATBUFFERS_TD, you can use a variadic macro (with __VA_ARGS__ if needed). -// In the above example, only CTYPE is used to generate the code, it can be rewritten: - -/* -switch (type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: \ - // do something specific to CTYPE here - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD -} -*/ - -#define FLATBUFFERS_GEN_TYPES(TD) \ - FLATBUFFERS_GEN_TYPES_SCALAR(TD) \ - FLATBUFFERS_GEN_TYPES_POINTER(TD) \ - FLATBUFFERS_GEN_TYPE_ARRAY(TD) - -// Create an enum for all the types above. -#ifdef __GNUC__ -__extension__ // Stop GCC complaining about trailing comma with -Wpendantic. -#endif -enum BaseType { - #define FLATBUFFERS_TD(ENUM, ...) \ - BASE_TYPE_ ## ENUM, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD -}; - -#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \ - "define largest_scalar_t as " #CTYPE); - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) -#undef FLATBUFFERS_TD - -inline bool IsScalar (BaseType t) { return t >= BASE_TYPE_UTYPE && - t <= BASE_TYPE_DOUBLE; } -inline bool IsInteger(BaseType t) { return t >= BASE_TYPE_UTYPE && - t <= BASE_TYPE_ULONG; } -inline bool IsFloat (BaseType t) { return t == BASE_TYPE_FLOAT || - t == BASE_TYPE_DOUBLE; } -inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG || - t == BASE_TYPE_ULONG; } -inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; } -inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE && - t <= BASE_TYPE_UCHAR; } - -inline bool IsUnsigned(BaseType t) { - return (t == BASE_TYPE_UTYPE) || (t == BASE_TYPE_UCHAR) || - (t == BASE_TYPE_USHORT) || (t == BASE_TYPE_UINT) || - (t == BASE_TYPE_ULONG); -} - -// clang-format on - -extern const char *const kTypeNames[]; -extern const char kTypeSizes[]; - -inline size_t SizeOf(BaseType t) { return kTypeSizes[t]; } - -struct StructDef; -struct EnumDef; -class Parser; - -// Represents any type in the IDL, which is a combination of the BaseType -// and additional information for vectors/structs_. -struct Type { - explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr, - EnumDef *_ed = nullptr, uint16_t _fixed_length = 0) - : base_type(_base_type), - element(BASE_TYPE_NONE), - struct_def(_sd), - enum_def(_ed), - fixed_length(_fixed_length) {} - - bool operator==(const Type &o) { - return base_type == o.base_type && element == o.element && - struct_def == o.struct_def && enum_def == o.enum_def; - } - - Type VectorType() const { - return Type(element, struct_def, enum_def, fixed_length); - } - - Offset Serialize(FlatBufferBuilder *builder) const; - - bool Deserialize(const Parser &parser, const reflection::Type *type); - - BaseType base_type; - BaseType element; // only set if t == BASE_TYPE_VECTOR - StructDef *struct_def; // only set if t or element == BASE_TYPE_STRUCT - EnumDef *enum_def; // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE, - // or for an integral type derived from an enum. - uint16_t fixed_length; // only set if t == BASE_TYPE_ARRAY -}; - -// Represents a parsed scalar value, it's type, and field offset. -struct Value { - Value() - : constant("0"), - offset(static_cast(~(static_cast(0U)))) {} - Type type; - std::string constant; - voffset_t offset; -}; - -// Helper class that retains the original order of a set of identifiers and -// also provides quick lookup. -template class SymbolTable { - public: - ~SymbolTable() { - for (auto it = vec.begin(); it != vec.end(); ++it) { delete *it; } - } - - bool Add(const std::string &name, T *e) { - vector_emplace_back(&vec, e); - auto it = dict.find(name); - if (it != dict.end()) return true; - dict[name] = e; - return false; - } - - void Move(const std::string &oldname, const std::string &newname) { - auto it = dict.find(oldname); - if (it != dict.end()) { - auto obj = it->second; - dict.erase(it); - dict[newname] = obj; - } else { - FLATBUFFERS_ASSERT(false); - } - } - - T *Lookup(const std::string &name) const { - auto it = dict.find(name); - return it == dict.end() ? nullptr : it->second; - } - - public: - std::map dict; // quick lookup - std::vector vec; // Used to iterate in order of insertion -}; - -// A name space, as set in the schema. -struct Namespace { - Namespace() : from_table(0) {} - - // Given a (potentially unqualified) name, return the "fully qualified" name - // which has a full namespaced descriptor. - // With max_components you can request less than the number of components - // the current namespace has. - std::string GetFullyQualifiedName(const std::string &name, - size_t max_components = 1000) const; - - std::vector components; - size_t from_table; // Part of the namespace corresponds to a message/table. -}; - -inline bool operator<(const Namespace &a, const Namespace &b) { - size_t min_size = std::min(a.components.size(), b.components.size()); - for (size_t i = 0; i < min_size; ++i) { - if (a.components[i] != b.components[i]) - return a.components[i] < b.components[i]; - } - return a.components.size() < b.components.size(); -} - -// Base class for all definition types (fields, structs_, enums_). -struct Definition { - Definition() - : generated(false), - defined_namespace(nullptr), - serialized_location(0), - index(-1), - refcount(1) {} - - flatbuffers::Offset< - flatbuffers::Vector>> - SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const; - - bool DeserializeAttributes(Parser &parser, - const Vector> *attrs); - - std::string name; - std::string file; - std::vector doc_comment; - SymbolTable attributes; - bool generated; // did we already output code for this definition? - Namespace *defined_namespace; // Where it was defined. - - // For use with Serialize() - uoffset_t serialized_location; - int index; // Inside the vector it is stored. - int refcount; -}; - -struct FieldDef : public Definition { - FieldDef() - : deprecated(false), - required(false), - key(false), - shared(false), - native_inline(false), - flexbuffer(false), - nested_flatbuffer(NULL), - padding(0) {} - - Offset Serialize(FlatBufferBuilder *builder, uint16_t id, - const Parser &parser) const; - - bool Deserialize(Parser &parser, const reflection::Field *field); - - Value value; - bool deprecated; // Field is allowed to be present in old data, but can't be. - // written in new data nor accessed in new code. - bool required; // Field must always be present. - bool key; // Field functions as a key for creating sorted vectors. - bool shared; // Field will be using string pooling (i.e. CreateSharedString) - // as default serialization behavior if field is a string. - bool native_inline; // Field will be defined inline (instead of as a pointer) - // for native tables if field is a struct. - bool flexbuffer; // This field contains FlexBuffer data. - StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data. - size_t padding; // Bytes to always pad after this field. -}; - -struct StructDef : public Definition { - StructDef() - : fixed(false), - predecl(true), - sortbysize(true), - has_key(false), - minalign(1), - bytesize(0) {} - - void PadLastField(size_t min_align) { - auto padding = PaddingBytes(bytesize, min_align); - bytesize += padding; - if (fields.vec.size()) fields.vec.back()->padding = padding; - } - - Offset Serialize(FlatBufferBuilder *builder, - const Parser &parser) const; - - bool Deserialize(Parser &parser, const reflection::Object *object); - - SymbolTable fields; - - bool fixed; // If it's struct, not a table. - bool predecl; // If it's used before it was defined. - bool sortbysize; // Whether fields come in the declaration or size order. - bool has_key; // It has a key field. - size_t minalign; // What the whole object needs to be aligned to. - size_t bytesize; // Size if fixed. - - flatbuffers::unique_ptr original_location; -}; - -struct EnumDef; -struct EnumValBuilder; - -struct EnumVal { - Offset Serialize(FlatBufferBuilder *builder, - const Parser &parser) const; - - bool Deserialize(const Parser &parser, const reflection::EnumVal *val); - - uint64_t GetAsUInt64() const { return static_cast(value); } - int64_t GetAsInt64() const { return value; } - bool IsZero() const { return 0 == value; } - bool IsNonZero() const { return !IsZero(); } - - std::string name; - std::vector doc_comment; - Type union_type; - - private: - friend EnumDef; - friend EnumValBuilder; - friend bool operator==(const EnumVal &lhs, const EnumVal &rhs); - - EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {} - EnumVal() : value(0) {} - - int64_t value; -}; - -struct EnumDef : public Definition { - EnumDef() : is_union(false), uses_multiple_type_instances(false) {} - - Offset Serialize(FlatBufferBuilder *builder, - const Parser &parser) const; - - bool Deserialize(Parser &parser, const reflection::Enum *values); - - template void ChangeEnumValue(EnumVal *ev, T new_val); - void SortByValue(); - void RemoveDuplicates(); - - std::string AllFlags() const; - const EnumVal *MinValue() const; - const EnumVal *MaxValue() const; - // Returns the number of integer steps from v1 to v2. - uint64_t Distance(const EnumVal *v1, const EnumVal *v2) const; - // Returns the number of integer steps from Min to Max. - uint64_t Distance() const { return Distance(MinValue(), MaxValue()); } - - EnumVal *ReverseLookup(int64_t enum_idx, - bool skip_union_default = false) const; - EnumVal *FindByValue(const std::string &constant) const; - - std::string ToString(const EnumVal &ev) const { - return IsUInt64() ? NumToString(ev.GetAsUInt64()) - : NumToString(ev.GetAsInt64()); - } - - size_t size() const { return vals.vec.size(); } - - const std::vector &Vals() const { return vals.vec; } - - const EnumVal *Lookup(const std::string &enum_name) const { - return vals.Lookup(enum_name); - } - - bool is_union; - // Type is a union which uses type aliases where at least one type is - // available under two different names. - bool uses_multiple_type_instances; - Type underlying_type; - - private: - bool IsUInt64() const { - return (BASE_TYPE_ULONG == underlying_type.base_type); - } - - friend EnumValBuilder; - SymbolTable vals; -}; - -inline bool IsStruct(const Type &type) { - return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed; -} - -inline bool IsUnion(const Type &type) { - return type.enum_def != nullptr && type.enum_def->is_union; -} - -inline bool IsVector(const Type &type) { - return type.base_type == BASE_TYPE_VECTOR; -} - -inline bool IsArray(const Type &type) { - return type.base_type == BASE_TYPE_ARRAY; -} - -inline bool IsSeries(const Type &type) { - return IsVector(type) || IsArray(type); -} - -inline bool IsEnum(const Type &type) { - return type.enum_def != nullptr && IsInteger(type.base_type); -} - -inline size_t InlineSize(const Type &type) { - return IsStruct(type) - ? type.struct_def->bytesize - : (IsArray(type) - ? InlineSize(type.VectorType()) * type.fixed_length - : SizeOf(type.base_type)); -} - -inline size_t InlineAlignment(const Type &type) { - if (IsStruct(type)) { - return type.struct_def->minalign; - } else if (IsArray(type)) { - return IsStruct(type.VectorType()) ? type.struct_def->minalign - : SizeOf(type.element); - } else { - return SizeOf(type.base_type); - } -} -inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) { - return lhs.value == rhs.value; -} -inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) { - return !(lhs == rhs); -} - -inline bool EqualByName(const Type &a, const Type &b) { - return a.base_type == b.base_type && a.element == b.element && - (a.struct_def == b.struct_def || - a.struct_def->name == b.struct_def->name) && - (a.enum_def == b.enum_def || a.enum_def->name == b.enum_def->name); -} - -struct RPCCall : public Definition { - Offset Serialize(FlatBufferBuilder *builder, - const Parser &parser) const; - - bool Deserialize(Parser &parser, const reflection::RPCCall *call); - - StructDef *request, *response; -}; - -struct ServiceDef : public Definition { - Offset Serialize(FlatBufferBuilder *builder, - const Parser &parser) const; - bool Deserialize(Parser &parser, const reflection::Service *service); - - SymbolTable calls; -}; - -// Container of options that may apply to any of the source/text generators. -struct IDLOptions { - // Use flexbuffers instead for binary and text generation - bool use_flexbuffers; - bool strict_json; - bool skip_js_exports; - bool use_goog_js_export_format; - bool use_ES6_js_export_format; - bool output_default_scalars_in_json; - int indent_step; - bool output_enum_identifiers; - bool prefixed_enums; - bool scoped_enums; - bool include_dependence_headers; - bool mutable_buffer; - bool one_file; - bool proto_mode; - bool proto_oneof_union; - bool generate_all; - bool skip_unexpected_fields_in_json; - bool generate_name_strings; - bool generate_object_based_api; - bool gen_compare; - std::string cpp_object_api_pointer_type; - std::string cpp_object_api_string_type; - bool cpp_object_api_string_flexible_constructor; - bool gen_nullable; - bool java_checkerframework; - bool gen_generated; - std::string object_prefix; - std::string object_suffix; - bool union_value_namespacing; - bool allow_non_utf8; - bool natural_utf8; - std::string include_prefix; - bool keep_include_path; - bool binary_schema_comments; - bool binary_schema_builtins; - bool binary_schema_gen_embed; - bool skip_flatbuffers_import; - std::string go_import; - std::string go_namespace; - bool reexport_ts_modules; - bool js_ts_short_names; - bool protobuf_ascii_alike; - bool size_prefixed; - std::string root_type; - bool force_defaults; - bool java_primitive_has_method; - bool cs_gen_json_serializer; - std::vector cpp_includes; - std::string cpp_std; - std::string proto_namespace_suffix; - std::string filename_suffix; - std::string filename_extension; - - // Possible options for the more general generator below. - enum Language { - kJava = 1 << 0, - kCSharp = 1 << 1, - kGo = 1 << 2, - kCpp = 1 << 3, - kJs = 1 << 4, - kPython = 1 << 5, - kPhp = 1 << 6, - kJson = 1 << 7, - kBinary = 1 << 8, - kTs = 1 << 9, - kJsonSchema = 1 << 10, - kDart = 1 << 11, - kLua = 1 << 12, - kLobster = 1 << 13, - kRust = 1 << 14, - kKotlin = 1 << 15, - kSwift = 1 << 16, - kMAX - }; - - Language lang; - - enum MiniReflect { kNone, kTypes, kTypesAndNames }; - - MiniReflect mini_reflect; - - // The corresponding language bit will be set if a language is included - // for code generation. - unsigned long lang_to_generate; - - // If set (default behavior), empty string fields will be set to nullptr to - // make the flatbuffer more compact. - bool set_empty_strings_to_null; - - // If set (default behavior), empty vector fields will be set to nullptr to - // make the flatbuffer more compact. - bool set_empty_vectors_to_null; - - IDLOptions() - : use_flexbuffers(false), - strict_json(false), - skip_js_exports(false), - use_goog_js_export_format(false), - use_ES6_js_export_format(false), - output_default_scalars_in_json(false), - indent_step(2), - output_enum_identifiers(true), - prefixed_enums(true), - scoped_enums(false), - include_dependence_headers(true), - mutable_buffer(false), - one_file(false), - proto_mode(false), - proto_oneof_union(false), - generate_all(false), - skip_unexpected_fields_in_json(false), - generate_name_strings(false), - generate_object_based_api(false), - gen_compare(false), - cpp_object_api_pointer_type("std::unique_ptr"), - cpp_object_api_string_flexible_constructor(false), - gen_nullable(false), - java_checkerframework(false), - gen_generated(false), - object_suffix("T"), - union_value_namespacing(true), - allow_non_utf8(false), - natural_utf8(false), - keep_include_path(false), - binary_schema_comments(false), - binary_schema_builtins(false), - binary_schema_gen_embed(false), - skip_flatbuffers_import(false), - reexport_ts_modules(true), - js_ts_short_names(false), - protobuf_ascii_alike(false), - size_prefixed(false), - force_defaults(false), - java_primitive_has_method(false), - cs_gen_json_serializer(false), - filename_suffix("_generated"), - filename_extension(), - lang(IDLOptions::kJava), - mini_reflect(IDLOptions::kNone), - lang_to_generate(0), - set_empty_strings_to_null(true), - set_empty_vectors_to_null(true) {} -}; - -// This encapsulates where the parser is in the current source file. -struct ParserState { - ParserState() - : cursor_(nullptr), - line_start_(nullptr), - line_(0), - token_(-1), - attr_is_trivial_ascii_string_(true) {} - - protected: - void ResetState(const char *source) { - cursor_ = source; - line_ = 0; - MarkNewLine(); - } - - void MarkNewLine() { - line_start_ = cursor_; - line_ += 1; - } - - int64_t CursorPosition() const { - FLATBUFFERS_ASSERT(cursor_ && line_start_ && cursor_ >= line_start_); - return static_cast(cursor_ - line_start_); - } - - const char *cursor_; - const char *line_start_; - int line_; // the current line being parsed - int token_; - - // Flag: text in attribute_ is true ASCII string without escape - // sequences. Only printable ASCII (without [\t\r\n]). - // Used for number-in-string (and base64 string in future). - bool attr_is_trivial_ascii_string_; - std::string attribute_; - std::vector doc_comment_; -}; - -// A way to make error propagation less error prone by requiring values to be -// checked. -// Once you create a value of this type you must either: -// - Call Check() on it. -// - Copy or assign it to another value. -// Failure to do so leads to an assert. -// This guarantees that this as return value cannot be ignored. -class CheckedError { - public: - explicit CheckedError(bool error) - : is_error_(error), has_been_checked_(false) {} - - CheckedError &operator=(const CheckedError &other) { - is_error_ = other.is_error_; - has_been_checked_ = false; - other.has_been_checked_ = true; - return *this; - } - - CheckedError(const CheckedError &other) { - *this = other; // Use assignment operator. - } - - ~CheckedError() { FLATBUFFERS_ASSERT(has_been_checked_); } - - bool Check() { - has_been_checked_ = true; - return is_error_; - } - - private: - bool is_error_; - mutable bool has_been_checked_; -}; - -// Additionally, in GCC we can get these errors statically, for additional -// assurance: -// clang-format off -#ifdef __GNUC__ -#define FLATBUFFERS_CHECKED_ERROR CheckedError \ - __attribute__((warn_unused_result)) -#else -#define FLATBUFFERS_CHECKED_ERROR CheckedError -#endif -// clang-format on - -class Parser : public ParserState { - public: - explicit Parser(const IDLOptions &options = IDLOptions()) - : current_namespace_(nullptr), - empty_namespace_(nullptr), - flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL), - root_struct_def_(nullptr), - opts(options), - uses_flexbuffers_(false), - source_(nullptr), - anonymous_counter(0), - recurse_protection_counter(0) { - if (opts.force_defaults) { builder_.ForceDefaults(true); } - // Start out with the empty namespace being current. - empty_namespace_ = new Namespace(); - namespaces_.push_back(empty_namespace_); - current_namespace_ = empty_namespace_; - known_attributes_["deprecated"] = true; - known_attributes_["required"] = true; - known_attributes_["key"] = true; - known_attributes_["shared"] = true; - known_attributes_["hash"] = true; - known_attributes_["id"] = true; - known_attributes_["force_align"] = true; - known_attributes_["bit_flags"] = true; - known_attributes_["original_order"] = true; - known_attributes_["nested_flatbuffer"] = true; - known_attributes_["csharp_partial"] = true; - known_attributes_["streaming"] = true; - known_attributes_["idempotent"] = true; - known_attributes_["cpp_type"] = true; - known_attributes_["cpp_ptr_type"] = true; - known_attributes_["cpp_ptr_type_get"] = true; - known_attributes_["cpp_str_type"] = true; - known_attributes_["cpp_str_flex_ctor"] = true; - known_attributes_["native_inline"] = true; - known_attributes_["native_custom_alloc"] = true; - known_attributes_["native_type"] = true; - known_attributes_["native_default"] = true; - known_attributes_["flexbuffer"] = true; - known_attributes_["private"] = true; - } - - ~Parser() { - for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) { - delete *it; - } - } - - // Parse the string containing either schema or JSON data, which will - // populate the SymbolTable's or the FlatBufferBuilder above. - // include_paths is used to resolve any include statements, and typically - // should at least include the project path (where you loaded source_ from). - // include_paths must be nullptr terminated if specified. - // If include_paths is nullptr, it will attempt to load from the current - // directory. - // If the source was loaded from a file and isn't an include file, - // supply its name in source_filename. - // All paths specified in this call must be in posix format, if you accept - // paths from user input, please call PosixPath on them first. - bool Parse(const char *_source, const char **include_paths = nullptr, - const char *source_filename = nullptr); - - // Set the root type. May override the one set in the schema. - bool SetRootType(const char *name); - - // Mark all definitions as already having code generated. - void MarkGenerated(); - - // Get the files recursively included by the given file. The returned - // container will have at least the given file. - std::set GetIncludedFilesRecursive( - const std::string &file_name) const; - - // Fills builder_ with a binary version of the schema parsed. - // See reflection/reflection.fbs - void Serialize(); - - // Deserialize a schema buffer - bool Deserialize(const uint8_t *buf, const size_t size); - - // Fills internal structure as if the schema passed had been loaded by parsing - // with Parse except that included filenames will not be populated. - bool Deserialize(const reflection::Schema *schema); - - Type *DeserializeType(const reflection::Type *type); - - // Checks that the schema represented by this parser is a safe evolution - // of the schema provided. Returns non-empty error on any problems. - std::string ConformTo(const Parser &base); - - // Similar to Parse(), but now only accepts JSON to be parsed into a - // FlexBuffer. - bool ParseFlexBuffer(const char *source, const char *source_filename, - flexbuffers::Builder *builder); - - StructDef *LookupStruct(const std::string &id) const; - - std::string UnqualifiedName(const std::string &fullQualifiedName); - - FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg); - - private: - void Message(const std::string &msg); - void Warning(const std::string &msg); - FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val); - FLATBUFFERS_CHECKED_ERROR Next(); - FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark(); - bool Is(int t) const; - bool IsIdent(const char *id) const; - FLATBUFFERS_CHECKED_ERROR Expect(int t); - std::string TokenToStringId(int t) const; - EnumDef *LookupEnum(const std::string &id); - FLATBUFFERS_CHECKED_ERROR ParseNamespacing(std::string *id, - std::string *last); - FLATBUFFERS_CHECKED_ERROR ParseTypeIdent(Type &type); - FLATBUFFERS_CHECKED_ERROR ParseType(Type &type); - FLATBUFFERS_CHECKED_ERROR AddField(StructDef &struct_def, - const std::string &name, const Type &type, - FieldDef **dest); - FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def); - FLATBUFFERS_CHECKED_ERROR ParseString(Value &val, bool use_string_pooling); - FLATBUFFERS_CHECKED_ERROR ParseComma(); - FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field, - size_t parent_fieldn, - const StructDef *parent_struct_def, - uoffset_t count, - bool inside_vector = false); - template - FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn, - const StructDef *struct_def, - F body); - FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def, - std::string *value, uoffset_t *ovalue); - void SerializeStruct(const StructDef &struct_def, const Value &val); - void SerializeStruct(FlatBufferBuilder &builder, const StructDef &struct_def, - const Value &val); - template - FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(uoffset_t &count, F body); - FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue, - FieldDef *field, size_t fieldn); - FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array); - FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer( - Value &val, FieldDef *field, size_t fieldn, - const StructDef *parent_struct_def); - FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable *attributes); - FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken, - bool check, Value &e, BaseType req, - bool *destmatch); - FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field); - FLATBUFFERS_CHECKED_ERROR TokenError(); - FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e, - bool check_now); - FLATBUFFERS_CHECKED_ERROR ParseFunction(const std::string *name, Value &e); - FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type, - std::string *result); - StructDef *LookupCreateStruct(const std::string &name, - bool create_if_new = true, - bool definition = false); - FLATBUFFERS_CHECKED_ERROR ParseEnum(bool is_union, EnumDef **dest); - FLATBUFFERS_CHECKED_ERROR ParseNamespace(); - FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name, - StructDef **dest); - FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union, - EnumDef **dest); - FLATBUFFERS_CHECKED_ERROR ParseDecl(); - FLATBUFFERS_CHECKED_ERROR ParseService(); - FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def, - bool isextend, bool inside_oneof); - FLATBUFFERS_CHECKED_ERROR ParseProtoOption(); - FLATBUFFERS_CHECKED_ERROR ParseProtoKey(); - FLATBUFFERS_CHECKED_ERROR ParseProtoDecl(); - FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent(); - FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type); - FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue(); - FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder); - FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source, - const char *source_filename); - FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source, - const char **include_paths, - const char *source_filename); - FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source, - const char **include_paths, - const char *source_filename, - const char *include_filename); - FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector &fields, - StructDef *struct_def, - const char *suffix, BaseType baseType); - - bool SupportsAdvancedUnionFeatures() const; - bool SupportsAdvancedArrayFeatures() const; - Namespace *UniqueNamespace(Namespace *ns); - - FLATBUFFERS_CHECKED_ERROR RecurseError(); - template CheckedError Recurse(F f); - - public: - SymbolTable types_; - SymbolTable structs_; - SymbolTable enums_; - SymbolTable services_; - std::vector namespaces_; - Namespace *current_namespace_; - Namespace *empty_namespace_; - std::string error_; // User readable error_ if Parse() == false - - FlatBufferBuilder builder_; // any data contained in the file - flexbuffers::Builder flex_builder_; - flexbuffers::Reference flex_root_; - StructDef *root_struct_def_; - std::string file_identifier_; - std::string file_extension_; - - std::map included_files_; - std::map> files_included_per_file_; - std::vector native_included_files_; - - std::map known_attributes_; - - IDLOptions opts; - bool uses_flexbuffers_; - - private: - const char *source_; - - std::string file_being_parsed_; - - std::vector> field_stack_; - - int anonymous_counter; - int recurse_protection_counter; -}; - -// Utility functions for multiple generators: - -extern std::string MakeCamel(const std::string &in, bool first = true); - -extern std::string MakeScreamingCamel(const std::string &in); - -// Generate text (JSON) from a given FlatBuffer, and a given Parser -// object that has been populated with the corresponding schema. -// If ident_step is 0, no indentation will be generated. Additionally, -// if it is less than 0, no linefeeds will be generated either. -// See idl_gen_text.cpp. -// strict_json adds "quotes" around field names if true. -// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8 -// byte arrays in String values), returns false. -extern bool GenerateTextFromTable(const Parser &parser, const void *table, - const std::string &tablename, - std::string *text); -extern bool GenerateText(const Parser &parser, const void *flatbuffer, - std::string *text); -extern bool GenerateTextFile(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate binary files from a given FlatBuffer, and a given Parser -// object that has been populated with the corresponding schema. -// See code_generators.cpp. -extern bool GenerateBinary(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a C++ header from the definitions in the Parser object. -// See idl_gen_cpp. -extern bool GenerateCPP(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate C# files from the definitions in the Parser object. -// See idl_gen_csharp.cpp. -extern bool GenerateCSharp(const Parser &parser, const std::string &path, - const std::string &file_name); - -extern bool GenerateDart(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Java files from the definitions in the Parser object. -// See idl_gen_java.cpp. -extern bool GenerateJava(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate JavaScript or TypeScript code from the definitions in the Parser -// object. See idl_gen_js. -extern bool GenerateJSTS(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Go files from the definitions in the Parser object. -// See idl_gen_go.cpp. -extern bool GenerateGo(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Php code from the definitions in the Parser object. -// See idl_gen_php. -extern bool GeneratePhp(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Python files from the definitions in the Parser object. -// See idl_gen_python.cpp. -extern bool GeneratePython(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Lobster files from the definitions in the Parser object. -// See idl_gen_lobster.cpp. -extern bool GenerateLobster(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Lua files from the definitions in the Parser object. -// See idl_gen_lua.cpp. -extern bool GenerateLua(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Rust files from the definitions in the Parser object. -// See idl_gen_rust.cpp. -extern bool GenerateRust(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Json schema file -// See idl_gen_json_schema.cpp. -extern bool GenerateJsonSchema(const Parser &parser, const std::string &path, - const std::string &file_name); - -extern bool GenerateKotlin(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate Swift classes. -// See idl_gen_swift.cpp -extern bool GenerateSwift(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a schema file from the internal representation, useful after -// parsing a .proto schema. -extern std::string GenerateFBS(const Parser &parser, - const std::string &file_name); -extern bool GenerateFBS(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a make rule for the generated JavaScript or TypeScript code. -// See idl_gen_js.cpp. -extern std::string JSTSMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a make rule for the generated C++ header. -// See idl_gen_cpp.cpp. -extern std::string CPPMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a make rule for the generated Dart code -// see idl_gen_dart.cpp -extern std::string DartMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a make rule for the generated Rust code. -// See idl_gen_rust.cpp. -extern std::string RustMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate a make rule for generated Java or C# files. -// See code_generators.cpp. -extern std::string JavaCSharpMakeRule(const Parser &parser, - const std::string &path, - const std::string &file_name); - -// Generate a make rule for the generated text (JSON) files. -// See idl_gen_text.cpp. -extern std::string TextMakeRule(const Parser &parser, const std::string &path, - const std::string &file_names); - -// Generate a make rule for the generated binary files. -// See code_generators.cpp. -extern std::string BinaryMakeRule(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Cpp interfaces. -// See idl_gen_grpc.cpp. -bool GenerateCppGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Go interfaces. -// See idl_gen_grpc.cpp. -bool GenerateGoGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Java classes. -// See idl_gen_grpc.cpp -bool GenerateJavaGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Python interfaces. -// See idl_gen_grpc.cpp. -bool GeneratePythonGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -// Generate GRPC Swift interfaces. -// See idl_gen_grpc.cpp. -extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path, - const std::string &file_name); - -} // namespace flatbuffers - -#endif // FLATBUFFERS_IDL_H_ diff --git a/daemon/src/External/include/flatbuffers/minireflect.h b/daemon/src/External/include/flatbuffers/minireflect.h deleted file mode 100644 index c2babdcc..00000000 --- a/daemon/src/External/include/flatbuffers/minireflect.h +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_MINIREFLECT_H_ -#define FLATBUFFERS_MINIREFLECT_H_ - -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -// Utilities that can be used with the "mini reflection" tables present -// in generated code with --reflect-types (only types) or --reflect-names -// (also names). -// This allows basic reflection functionality such as pretty-printing -// that does not require the use of the schema parser or loading of binary -// schema files at runtime (reflection.h). - -// For any of the functions below that take `const TypeTable *`, you pass -// `FooTypeTable()` if the type of the root is `Foo`. - -// First, a generic iterator that can be used by multiple algorithms. - -struct IterationVisitor { - // These mark the scope of a table or struct. - virtual void StartSequence() {} - virtual void EndSequence() {} - // Called for each field regardless of whether it is present or not. - // If not present, val == nullptr. set_idx is the index of all set fields. - virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/, - ElementaryType /*type*/, bool /*is_vector*/, - const TypeTable * /*type_table*/, const char * /*name*/, - const uint8_t * /*val*/) {} - // Called for a value that is actually present, after a field, or as part - // of a vector. - virtual void UType(uint8_t, const char *) {} - virtual void Bool(bool) {} - virtual void Char(int8_t, const char *) {} - virtual void UChar(uint8_t, const char *) {} - virtual void Short(int16_t, const char *) {} - virtual void UShort(uint16_t, const char *) {} - virtual void Int(int32_t, const char *) {} - virtual void UInt(uint32_t, const char *) {} - virtual void Long(int64_t) {} - virtual void ULong(uint64_t) {} - virtual void Float(float) {} - virtual void Double(double) {} - virtual void String(const String *) {} - virtual void Unknown(const uint8_t *) {} // From a future version. - // These mark the scope of a vector. - virtual void StartVector() {} - virtual void EndVector() {} - virtual void Element(size_t /*i*/, ElementaryType /*type*/, - const TypeTable * /*type_table*/, - const uint8_t * /*val*/) {} - virtual ~IterationVisitor() {} -}; - -inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) { - switch (type) { - case ET_UTYPE: - case ET_BOOL: - case ET_CHAR: - case ET_UCHAR: return 1; - case ET_SHORT: - case ET_USHORT: return 2; - case ET_INT: - case ET_UINT: - case ET_FLOAT: - case ET_STRING: return 4; - case ET_LONG: - case ET_ULONG: - case ET_DOUBLE: return 8; - case ET_SEQUENCE: - switch (type_table->st) { - case ST_TABLE: - case ST_UNION: return 4; - case ST_STRUCT: - return static_cast(type_table->values[type_table->num_elems]); - default: FLATBUFFERS_ASSERT(false); return 1; - } - default: FLATBUFFERS_ASSERT(false); return 1; - } -} - -inline int64_t LookupEnum(int64_t enum_val, const int64_t *values, - size_t num_values) { - if (!values) return enum_val; - for (size_t i = 0; i < num_values; i++) { - if (enum_val == values[i]) return static_cast(i); - } - return -1; // Unknown enum value. -} - -template const char *EnumName(T tval, const TypeTable *type_table) { - if (!type_table || !type_table->names) return nullptr; - auto i = LookupEnum(static_cast(tval), type_table->values, - type_table->num_elems); - if (i >= 0 && i < static_cast(type_table->num_elems)) { - return type_table->names[i]; - } - return nullptr; -} - -void IterateObject(const uint8_t *obj, const TypeTable *type_table, - IterationVisitor *visitor); - -inline void IterateValue(ElementaryType type, const uint8_t *val, - const TypeTable *type_table, const uint8_t *prev_val, - soffset_t vector_index, IterationVisitor *visitor) { - switch (type) { - case ET_UTYPE: { - auto tval = ReadScalar(val); - visitor->UType(tval, EnumName(tval, type_table)); - break; - } - case ET_BOOL: { - visitor->Bool(ReadScalar(val) != 0); - break; - } - case ET_CHAR: { - auto tval = ReadScalar(val); - visitor->Char(tval, EnumName(tval, type_table)); - break; - } - case ET_UCHAR: { - auto tval = ReadScalar(val); - visitor->UChar(tval, EnumName(tval, type_table)); - break; - } - case ET_SHORT: { - auto tval = ReadScalar(val); - visitor->Short(tval, EnumName(tval, type_table)); - break; - } - case ET_USHORT: { - auto tval = ReadScalar(val); - visitor->UShort(tval, EnumName(tval, type_table)); - break; - } - case ET_INT: { - auto tval = ReadScalar(val); - visitor->Int(tval, EnumName(tval, type_table)); - break; - } - case ET_UINT: { - auto tval = ReadScalar(val); - visitor->UInt(tval, EnumName(tval, type_table)); - break; - } - case ET_LONG: { - visitor->Long(ReadScalar(val)); - break; - } - case ET_ULONG: { - visitor->ULong(ReadScalar(val)); - break; - } - case ET_FLOAT: { - visitor->Float(ReadScalar(val)); - break; - } - case ET_DOUBLE: { - visitor->Double(ReadScalar(val)); - break; - } - case ET_STRING: { - val += ReadScalar(val); - visitor->String(reinterpret_cast(val)); - break; - } - case ET_SEQUENCE: { - switch (type_table->st) { - case ST_TABLE: - val += ReadScalar(val); - IterateObject(val, type_table, visitor); - break; - case ST_STRUCT: IterateObject(val, type_table, visitor); break; - case ST_UNION: { - val += ReadScalar(val); - FLATBUFFERS_ASSERT(prev_val); - auto union_type = *prev_val; // Always a uint8_t. - if (vector_index >= 0) { - auto type_vec = reinterpret_cast *>(prev_val); - union_type = type_vec->Get(static_cast(vector_index)); - } - auto type_code_idx = - LookupEnum(union_type, type_table->values, type_table->num_elems); - if (type_code_idx >= 0 && - type_code_idx < static_cast(type_table->num_elems)) { - auto type_code = type_table->type_codes[type_code_idx]; - switch (type_code.base_type) { - case ET_SEQUENCE: { - auto ref = type_table->type_refs[type_code.sequence_ref](); - IterateObject(val, ref, visitor); - break; - } - case ET_STRING: - visitor->String(reinterpret_cast(val)); - break; - default: visitor->Unknown(val); - } - } else { - visitor->Unknown(val); - } - break; - } - case ST_ENUM: FLATBUFFERS_ASSERT(false); break; - } - break; - } - default: { - visitor->Unknown(val); - break; - } - } -} - -inline void IterateObject(const uint8_t *obj, const TypeTable *type_table, - IterationVisitor *visitor) { - visitor->StartSequence(); - const uint8_t *prev_val = nullptr; - size_t set_idx = 0; - for (size_t i = 0; i < type_table->num_elems; i++) { - auto type_code = type_table->type_codes[i]; - auto type = static_cast(type_code.base_type); - auto is_vector = type_code.is_vector != 0; - auto ref_idx = type_code.sequence_ref; - const TypeTable *ref = nullptr; - if (ref_idx >= 0) { ref = type_table->type_refs[ref_idx](); } - auto name = type_table->names ? type_table->names[i] : nullptr; - const uint8_t *val = nullptr; - if (type_table->st == ST_TABLE) { - val = reinterpret_cast(obj)->GetAddressOf( - FieldIndexToOffset(static_cast(i))); - } else { - val = obj + type_table->values[i]; - } - visitor->Field(i, set_idx, type, is_vector, ref, name, val); - if (val) { - set_idx++; - if (is_vector) { - val += ReadScalar(val); - auto vec = reinterpret_cast *>(val); - visitor->StartVector(); - auto elem_ptr = vec->Data(); - for (size_t j = 0; j < vec->size(); j++) { - visitor->Element(j, type, ref, elem_ptr); - IterateValue(type, elem_ptr, ref, prev_val, static_cast(j), - visitor); - elem_ptr += InlineSize(type, ref); - } - visitor->EndVector(); - } else { - IterateValue(type, val, ref, prev_val, -1, visitor); - } - } - prev_val = val; - } - visitor->EndSequence(); -} - -inline void IterateFlatBuffer(const uint8_t *buffer, - const TypeTable *type_table, - IterationVisitor *callback) { - IterateObject(GetRoot(buffer), type_table, callback); -} - -// Outputting a Flatbuffer to a string. Tries to conform as close to JSON / -// the output generated by idl_gen_text.cpp. - -struct ToStringVisitor : public IterationVisitor { - std::string s; - std::string d; - bool q; - std::string in; - size_t indent_level; - bool vector_delimited; - ToStringVisitor(std::string delimiter, bool quotes, std::string indent, - bool vdelimited = true) - : d(delimiter), - q(quotes), - in(indent), - indent_level(0), - vector_delimited(vdelimited) {} - ToStringVisitor(std::string delimiter) - : d(delimiter), - q(false), - in(""), - indent_level(0), - vector_delimited(true) {} - - void append_indent() { - for (size_t i = 0; i < indent_level; i++) { s += in; } - } - - void StartSequence() { - s += "{"; - s += d; - indent_level++; - } - void EndSequence() { - s += d; - indent_level--; - append_indent(); - s += "}"; - } - void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/, - bool /*is_vector*/, const TypeTable * /*type_table*/, - const char *name, const uint8_t *val) { - if (!val) return; - if (set_idx) { - s += ","; - s += d; - } - append_indent(); - if (name) { - if (q) s += "\""; - s += name; - if (q) s += "\""; - s += ": "; - } - } - template void Named(T x, const char *name) { - if (name) { - if (q) s += "\""; - s += name; - if (q) s += "\""; - } else { - s += NumToString(x); - } - } - void UType(uint8_t x, const char *name) { Named(x, name); } - void Bool(bool x) { s += x ? "true" : "false"; } - void Char(int8_t x, const char *name) { Named(x, name); } - void UChar(uint8_t x, const char *name) { Named(x, name); } - void Short(int16_t x, const char *name) { Named(x, name); } - void UShort(uint16_t x, const char *name) { Named(x, name); } - void Int(int32_t x, const char *name) { Named(x, name); } - void UInt(uint32_t x, const char *name) { Named(x, name); } - void Long(int64_t x) { s += NumToString(x); } - void ULong(uint64_t x) { s += NumToString(x); } - void Float(float x) { s += NumToString(x); } - void Double(double x) { s += NumToString(x); } - void String(const struct String *str) { - EscapeString(str->c_str(), str->size(), &s, true, false); - } - void Unknown(const uint8_t *) { s += "(?)"; } - void StartVector() { - s += "["; - if (vector_delimited) { - s += d; - indent_level++; - append_indent(); - } else { - s += " "; - } - } - void EndVector() { - if (vector_delimited) { - s += d; - indent_level--; - append_indent(); - } else { - s += " "; - } - s += "]"; - } - void Element(size_t i, ElementaryType /*type*/, - const TypeTable * /*type_table*/, const uint8_t * /*val*/) { - if (i) { - s += ","; - if (vector_delimited) { - s += d; - append_indent(); - } else { - s += " "; - } - } - } -}; - -inline std::string FlatBufferToString(const uint8_t *buffer, - const TypeTable *type_table, - bool multi_line = false, - bool vector_delimited = true) { - ToStringVisitor tostring_visitor(multi_line ? "\n" : " ", false, "", - vector_delimited); - IterateFlatBuffer(buffer, type_table, &tostring_visitor); - return tostring_visitor.s; -} - -} // namespace flatbuffers - -#endif // FLATBUFFERS_MINIREFLECT_H_ diff --git a/daemon/src/External/include/flatbuffers/pch/flatc_pch.h b/daemon/src/External/include/flatbuffers/pch/flatc_pch.h deleted file mode 100644 index 77132790..00000000 --- a/daemon/src/External/include/flatbuffers/pch/flatc_pch.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_FLATC_PCH_H_ -#define FLATBUFFERS_FLATC_PCH_H_ - -// stl -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// flatbuffers -#include "flatbuffers/pch/pch.h" -#include "flatbuffers/code_generators.h" -#include "flatbuffers/flatbuffers.h" -#include "flatbuffers/flexbuffers.h" -#include "flatbuffers/idl.h" - -#endif // FLATBUFFERS_FLATC_PCH_H_ diff --git a/daemon/src/External/include/flatbuffers/pch/pch.h b/daemon/src/External/include/flatbuffers/pch/pch.h deleted file mode 100644 index 804e99ed..00000000 --- a/daemon/src/External/include/flatbuffers/pch/pch.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_PCH_H_ -#define FLATBUFFERS_PCH_H_ - -// stl -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// flatbuffers -#include "flatbuffers/util.h" - -#endif // FLATBUFFERS_PCH_H_ diff --git a/daemon/src/External/include/flatbuffers/reflection.h b/daemon/src/External/include/flatbuffers/reflection.h deleted file mode 100644 index 70d9971f..00000000 --- a/daemon/src/External/include/flatbuffers/reflection.h +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright 2015 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_REFLECTION_H_ -#define FLATBUFFERS_REFLECTION_H_ - -// This is somewhat of a circular dependency because flatc (and thus this -// file) is needed to generate this header in the first place. -// Should normally not be a problem since it can be generated by the -// previous version of flatc whenever this code needs to change. -// See reflection/generate_code.sh -#include "flatbuffers/reflection_generated.h" - -// Helper functionality for reflection. - -namespace flatbuffers { - -// ------------------------- GETTERS ------------------------- - -inline bool IsScalar(reflection::BaseType t) { - return t >= reflection::UType && t <= reflection::Double; -} -inline bool IsInteger(reflection::BaseType t) { - return t >= reflection::UType && t <= reflection::ULong; -} -inline bool IsFloat(reflection::BaseType t) { - return t == reflection::Float || t == reflection::Double; -} -inline bool IsLong(reflection::BaseType t) { - return t == reflection::Long || t == reflection::ULong; -} - -// Size of a basic type, don't use with structs. -inline size_t GetTypeSize(reflection::BaseType base_type) { - // This needs to correspond to the BaseType enum. - static size_t sizes[] = { - 0, // None - 1, // UType - 1, // Bool - 1, // Byte - 1, // UByte - 2, // Short - 2, // UShort - 4, // Int - 4, // UInt - 8, // Long - 8, // ULong - 4, // Float - 8, // Double - 4, // String - 4, // Vector - 4, // Obj - 4, // Union - 0, // Array. Only used in structs. 0 was chosen to prevent out-of-bounds errors. - - 0 // MaxBaseType. This must be kept the last entry in this array. - }; - static_assert(sizeof(sizes) / sizeof(size_t) == reflection::MaxBaseType + 1, - "Size of sizes[] array does not match the count of BaseType enum values."); - return sizes[base_type]; -} - -// Same as above, but now correctly returns the size of a struct if -// the field (or vector element) is a struct. -inline size_t GetTypeSizeInline(reflection::BaseType base_type, int type_index, - const reflection::Schema &schema) { - if (base_type == reflection::Obj && - schema.objects()->Get(type_index)->is_struct()) { - return schema.objects()->Get(type_index)->bytesize(); - } else { - return GetTypeSize(base_type); - } -} - -// Get the root, regardless of what type it is. -inline Table *GetAnyRoot(uint8_t *flatbuf) { - return GetMutableRoot
(flatbuf); -} -inline const Table *GetAnyRoot(const uint8_t *flatbuf) { - return GetRoot
(flatbuf); -} - -// Get a field's default, if you know it's an integer, and its exact type. -template T GetFieldDefaultI(const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); - return static_cast(field.default_integer()); -} - -// Get a field's default, if you know it's floating point and its exact type. -template T GetFieldDefaultF(const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); - return static_cast(field.default_real()); -} - -// Get a field, if you know it's an integer, and its exact type. -template -T GetFieldI(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); - return table.GetField(field.offset(), - static_cast(field.default_integer())); -} - -// Get a field, if you know it's floating point and its exact type. -template -T GetFieldF(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type())); - return table.GetField(field.offset(), - static_cast(field.default_real())); -} - -// Get a field, if you know it's a string. -inline const String *GetFieldS(const Table &table, - const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::String); - return table.GetPointer(field.offset()); -} - -// Get a field, if you know it's a vector. -template -Vector *GetFieldV(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Vector && - sizeof(T) == GetTypeSize(field.type()->element())); - return table.GetPointer *>(field.offset()); -} - -// Get a field, if you know it's a vector, generically. -// To actually access elements, use the return value together with -// field.type()->element() in any of GetAnyVectorElemI below etc. -inline VectorOfAny *GetFieldAnyV(const Table &table, - const reflection::Field &field) { - return table.GetPointer(field.offset()); -} - -// Get a field, if you know it's a table. -inline Table *GetFieldT(const Table &table, const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj || - field.type()->base_type() == reflection::Union); - return table.GetPointer
(field.offset()); -} - -// Get a field, if you know it's a struct. -inline const Struct *GetFieldStruct(const Table &table, - const reflection::Field &field) { - // TODO: This does NOT check if the field is a table or struct, but we'd need - // access to the schema to check the is_struct flag. - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj); - return table.GetStruct(field.offset()); -} - -// Get a structure's field, if you know it's a struct. -inline const Struct *GetFieldStruct(const Struct &structure, - const reflection::Field &field) { - FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj); - return structure.GetStruct(field.offset()); -} - -// Raw helper functions used below: get any value in memory as a 64bit int, a -// double or a string. -// All scalars get static_cast to an int64_t, strings use strtoull, every other -// data type returns 0. -int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data); -// All scalars static cast to double, strings use strtod, every other data -// type is 0.0. -double GetAnyValueF(reflection::BaseType type, const uint8_t *data); -// All scalars converted using stringstream, strings as-is, and all other -// data types provide some level of debug-pretty-printing. -std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data, - const reflection::Schema *schema, int type_index); - -// Get any table field as a 64bit int, regardless of what type it is. -inline int64_t GetAnyFieldI(const Table &table, - const reflection::Field &field) { - auto field_ptr = table.GetAddressOf(field.offset()); - return field_ptr ? GetAnyValueI(field.type()->base_type(), field_ptr) - : field.default_integer(); -} - -// Get any table field as a double, regardless of what type it is. -inline double GetAnyFieldF(const Table &table, const reflection::Field &field) { - auto field_ptr = table.GetAddressOf(field.offset()); - return field_ptr ? GetAnyValueF(field.type()->base_type(), field_ptr) - : field.default_real(); -} - -// Get any table field as a string, regardless of what type it is. -// You may pass nullptr for the schema if you don't care to have fields that -// are of table type pretty-printed. -inline std::string GetAnyFieldS(const Table &table, - const reflection::Field &field, - const reflection::Schema *schema) { - auto field_ptr = table.GetAddressOf(field.offset()); - return field_ptr ? GetAnyValueS(field.type()->base_type(), field_ptr, schema, - field.type()->index()) - : ""; -} - -// Get any struct field as a 64bit int, regardless of what type it is. -inline int64_t GetAnyFieldI(const Struct &st, const reflection::Field &field) { - return GetAnyValueI(field.type()->base_type(), - st.GetAddressOf(field.offset())); -} - -// Get any struct field as a double, regardless of what type it is. -inline double GetAnyFieldF(const Struct &st, const reflection::Field &field) { - return GetAnyValueF(field.type()->base_type(), - st.GetAddressOf(field.offset())); -} - -// Get any struct field as a string, regardless of what type it is. -inline std::string GetAnyFieldS(const Struct &st, - const reflection::Field &field) { - return GetAnyValueS(field.type()->base_type(), - st.GetAddressOf(field.offset()), nullptr, -1); -} - -// Get any vector element as a 64bit int, regardless of what type it is. -inline int64_t GetAnyVectorElemI(const VectorOfAny *vec, - reflection::BaseType elem_type, size_t i) { - return GetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i); -} - -// Get any vector element as a double, regardless of what type it is. -inline double GetAnyVectorElemF(const VectorOfAny *vec, - reflection::BaseType elem_type, size_t i) { - return GetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i); -} - -// Get any vector element as a string, regardless of what type it is. -inline std::string GetAnyVectorElemS(const VectorOfAny *vec, - reflection::BaseType elem_type, size_t i) { - return GetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i, - nullptr, -1); -} - -// Get a vector element that's a table/string/vector from a generic vector. -// Pass Table/String/VectorOfAny as template parameter. -// Warning: does no typechecking. -template -T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) { - auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i; - return reinterpret_cast(elem_ptr + ReadScalar(elem_ptr)); -} - -// Get the inline-address of a vector element. Useful for Structs (pass Struct -// as template arg), or being able to address a range of scalars in-line. -// Get elem_size from GetTypeSizeInline(). -// Note: little-endian data on all platforms, use EndianScalar() instead of -// raw pointer access with scalars). -template -T *GetAnyVectorElemAddressOf(const VectorOfAny *vec, size_t i, - size_t elem_size) { - return reinterpret_cast(vec->Data() + elem_size * i); -} - -// Similarly, for elements of tables. -template -T *GetAnyFieldAddressOf(const Table &table, const reflection::Field &field) { - return reinterpret_cast(table.GetAddressOf(field.offset())); -} - -// Similarly, for elements of structs. -template -T *GetAnyFieldAddressOf(const Struct &st, const reflection::Field &field) { - return reinterpret_cast(st.GetAddressOf(field.offset())); -} - -// ------------------------- SETTERS ------------------------- - -// Set any scalar field, if you know its exact type. -template -bool SetField(Table *table, const reflection::Field &field, T val) { - reflection::BaseType type = field.type()->base_type(); - if (!IsScalar(type)) { return false; } - FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type)); - T def; - if (IsInteger(type)) { - def = GetFieldDefaultI(field); - } else { - FLATBUFFERS_ASSERT(IsFloat(type)); - def = GetFieldDefaultF(field); - } - return table->SetField(field.offset(), val, def); -} - -// Raw helper functions used below: set any value in memory as a 64bit int, a -// double or a string. -// These work for all scalar values, but do nothing for other data types. -// To set a string, see SetString below. -void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val); -void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val); -void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val); - -// Set any table field as a 64bit int, regardless of type what it is. -inline bool SetAnyFieldI(Table *table, const reflection::Field &field, - int64_t val) { - auto field_ptr = table->GetAddressOf(field.offset()); - if (!field_ptr) return val == GetFieldDefaultI(field); - SetAnyValueI(field.type()->base_type(), field_ptr, val); - return true; -} - -// Set any table field as a double, regardless of what type it is. -inline bool SetAnyFieldF(Table *table, const reflection::Field &field, - double val) { - auto field_ptr = table->GetAddressOf(field.offset()); - if (!field_ptr) return val == GetFieldDefaultF(field); - SetAnyValueF(field.type()->base_type(), field_ptr, val); - return true; -} - -// Set any table field as a string, regardless of what type it is. -inline bool SetAnyFieldS(Table *table, const reflection::Field &field, - const char *val) { - auto field_ptr = table->GetAddressOf(field.offset()); - if (!field_ptr) return false; - SetAnyValueS(field.type()->base_type(), field_ptr, val); - return true; -} - -// Set any struct field as a 64bit int, regardless of type what it is. -inline void SetAnyFieldI(Struct *st, const reflection::Field &field, - int64_t val) { - SetAnyValueI(field.type()->base_type(), st->GetAddressOf(field.offset()), - val); -} - -// Set any struct field as a double, regardless of type what it is. -inline void SetAnyFieldF(Struct *st, const reflection::Field &field, - double val) { - SetAnyValueF(field.type()->base_type(), st->GetAddressOf(field.offset()), - val); -} - -// Set any struct field as a string, regardless of type what it is. -inline void SetAnyFieldS(Struct *st, const reflection::Field &field, - const char *val) { - SetAnyValueS(field.type()->base_type(), st->GetAddressOf(field.offset()), - val); -} - -// Set any vector element as a 64bit int, regardless of type what it is. -inline void SetAnyVectorElemI(VectorOfAny *vec, reflection::BaseType elem_type, - size_t i, int64_t val) { - SetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val); -} - -// Set any vector element as a double, regardless of type what it is. -inline void SetAnyVectorElemF(VectorOfAny *vec, reflection::BaseType elem_type, - size_t i, double val) { - SetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val); -} - -// Set any vector element as a string, regardless of type what it is. -inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type, - size_t i, const char *val) { - SetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val); -} - -// ------------------------- RESIZING SETTERS ------------------------- - -// "smart" pointer for use with resizing vectors: turns a pointer inside -// a vector into a relative offset, such that it is not affected by resizes. -template class pointer_inside_vector { - public: - pointer_inside_vector(T *ptr, std::vector &vec) - : offset_(reinterpret_cast(ptr) - - reinterpret_cast(flatbuffers::vector_data(vec))), - vec_(vec) {} - - T *operator*() const { - return reinterpret_cast( - reinterpret_cast(flatbuffers::vector_data(vec_)) + offset_); - } - T *operator->() const { return operator*(); } - - private: - size_t offset_; - std::vector &vec_; -}; - -// Helper to create the above easily without specifying template args. -template -pointer_inside_vector piv(T *ptr, std::vector &vec) { - return pointer_inside_vector(ptr, vec); -} - -inline const char *UnionTypeFieldSuffix() { return "_type"; } - -// Helper to figure out the actual table type a union refers to. -inline const reflection::Object &GetUnionType( - const reflection::Schema &schema, const reflection::Object &parent, - const reflection::Field &unionfield, const Table &table) { - auto enumdef = schema.enums()->Get(unionfield.type()->index()); - // TODO: this is clumsy and slow, but no other way to find it? - auto type_field = parent.fields()->LookupByKey( - (unionfield.name()->str() + UnionTypeFieldSuffix()).c_str()); - FLATBUFFERS_ASSERT(type_field); - auto union_type = GetFieldI(table, *type_field); - auto enumval = enumdef->values()->LookupByKey(union_type); - return *enumval->object(); -} - -// Changes the contents of a string inside a FlatBuffer. FlatBuffer must -// live inside a std::vector so we can resize the buffer if needed. -// "str" must live inside "flatbuf" and may be invalidated after this call. -// If your FlatBuffer's root table is not the schema's root table, you should -// pass in your root_table type as well. -void SetString(const reflection::Schema &schema, const std::string &val, - const String *str, std::vector *flatbuf, - const reflection::Object *root_table = nullptr); - -// Resizes a flatbuffers::Vector inside a FlatBuffer. FlatBuffer must -// live inside a std::vector so we can resize the buffer if needed. -// "vec" must live inside "flatbuf" and may be invalidated after this call. -// If your FlatBuffer's root table is not the schema's root table, you should -// pass in your root_table type as well. -uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize, - const VectorOfAny *vec, uoffset_t num_elems, - uoffset_t elem_size, std::vector *flatbuf, - const reflection::Object *root_table = nullptr); - -template -void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val, - const Vector *vec, std::vector *flatbuf, - const reflection::Object *root_table = nullptr) { - auto delta_elem = static_cast(newsize) - static_cast(vec->size()); - auto newelems = ResizeAnyVector( - schema, newsize, reinterpret_cast(vec), vec->size(), - static_cast(sizeof(T)), flatbuf, root_table); - // Set new elements to "val". - for (int i = 0; i < delta_elem; i++) { - auto loc = newelems + i * sizeof(T); - auto is_scalar = flatbuffers::is_scalar::value; - if (is_scalar) { - WriteScalar(loc, val); - } else { // struct - *reinterpret_cast(loc) = val; - } - } -} - -// Adds any new data (in the form of a new FlatBuffer) to an existing -// FlatBuffer. This can be used when any of the above methods are not -// sufficient, in particular for adding new tables and new fields. -// This is potentially slightly less efficient than a FlatBuffer constructed -// in one piece, since the new FlatBuffer doesn't share any vtables with the -// existing one. -// The return value can now be set using Vector::MutateOffset or SetFieldT -// below. -const uint8_t *AddFlatBuffer(std::vector &flatbuf, - const uint8_t *newbuf, size_t newlen); - -inline bool SetFieldT(Table *table, const reflection::Field &field, - const uint8_t *val) { - FLATBUFFERS_ASSERT(sizeof(uoffset_t) == - GetTypeSize(field.type()->base_type())); - return table->SetPointer(field.offset(), val); -} - -// ------------------------- COPYING ------------------------- - -// Generic copying of tables from a FlatBuffer into a FlatBuffer builder. -// Can be used to do any kind of merging/selecting you may want to do out -// of existing buffers. Also useful to reconstruct a whole buffer if the -// above resizing functionality has introduced garbage in a buffer you want -// to remove. -// Note: this does not deal with DAGs correctly. If the table passed forms a -// DAG, the copy will be a tree instead (with duplicates). Strings can be -// shared however, by passing true for use_string_pooling. - -Offset CopyTable(FlatBufferBuilder &fbb, - const reflection::Schema &schema, - const reflection::Object &objectdef, - const Table &table, - bool use_string_pooling = false); - -// Verifies the provided flatbuffer using reflection. -// root should point to the root type for this flatbuffer. -// buf should point to the start of flatbuffer data. -// length specifies the size of the flatbuffer data. -bool Verify(const reflection::Schema &schema, const reflection::Object &root, - const uint8_t *buf, size_t length, uoffset_t max_depth = 64, - uoffset_t max_tables = 1000000); - -} // namespace flatbuffers - -#endif // FLATBUFFERS_REFLECTION_H_ diff --git a/daemon/src/External/include/flatbuffers/reflection_generated.h b/daemon/src/External/include/flatbuffers/reflection_generated.h deleted file mode 100644 index 10b7dbf8..00000000 --- a/daemon/src/External/include/flatbuffers/reflection_generated.h +++ /dev/null @@ -1,1216 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - - -#ifndef FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_ -#define FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_ - -#include "flatbuffers/flatbuffers.h" - -namespace reflection { - -struct Type; -struct TypeBuilder; - -struct KeyValue; -struct KeyValueBuilder; - -struct EnumVal; -struct EnumValBuilder; - -struct Enum; -struct EnumBuilder; - -struct Field; -struct FieldBuilder; - -struct Object; -struct ObjectBuilder; - -struct RPCCall; -struct RPCCallBuilder; - -struct Service; -struct ServiceBuilder; - -struct Schema; -struct SchemaBuilder; - -enum BaseType { - None = 0, - UType = 1, - Bool = 2, - Byte = 3, - UByte = 4, - Short = 5, - UShort = 6, - Int = 7, - UInt = 8, - Long = 9, - ULong = 10, - Float = 11, - Double = 12, - String = 13, - Vector = 14, - Obj = 15, - Union = 16, - Array = 17, - MaxBaseType = 18 -}; - -inline const BaseType (&EnumValuesBaseType())[19] { - static const BaseType values[] = { - None, - UType, - Bool, - Byte, - UByte, - Short, - UShort, - Int, - UInt, - Long, - ULong, - Float, - Double, - String, - Vector, - Obj, - Union, - Array, - MaxBaseType - }; - return values; -} - -inline const char * const *EnumNamesBaseType() { - static const char * const names[20] = { - "None", - "UType", - "Bool", - "Byte", - "UByte", - "Short", - "UShort", - "Int", - "UInt", - "Long", - "ULong", - "Float", - "Double", - "String", - "Vector", - "Obj", - "Union", - "Array", - "MaxBaseType", - nullptr - }; - return names; -} - -inline const char *EnumNameBaseType(BaseType e) { - if (flatbuffers::IsOutRange(e, None, MaxBaseType)) return ""; - const size_t index = static_cast(e); - return EnumNamesBaseType()[index]; -} - -struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef TypeBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_BASE_TYPE = 4, - VT_ELEMENT = 6, - VT_INDEX = 8, - VT_FIXED_LENGTH = 10 - }; - reflection::BaseType base_type() const { - return static_cast(GetField(VT_BASE_TYPE, 0)); - } - reflection::BaseType element() const { - return static_cast(GetField(VT_ELEMENT, 0)); - } - int32_t index() const { - return GetField(VT_INDEX, -1); - } - uint16_t fixed_length() const { - return GetField(VT_FIXED_LENGTH, 0); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_BASE_TYPE) && - VerifyField(verifier, VT_ELEMENT) && - VerifyField(verifier, VT_INDEX) && - VerifyField(verifier, VT_FIXED_LENGTH) && - verifier.EndTable(); - } -}; - -struct TypeBuilder { - typedef Type Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_base_type(reflection::BaseType base_type) { - fbb_.AddElement(Type::VT_BASE_TYPE, static_cast(base_type), 0); - } - void add_element(reflection::BaseType element) { - fbb_.AddElement(Type::VT_ELEMENT, static_cast(element), 0); - } - void add_index(int32_t index) { - fbb_.AddElement(Type::VT_INDEX, index, -1); - } - void add_fixed_length(uint16_t fixed_length) { - fbb_.AddElement(Type::VT_FIXED_LENGTH, fixed_length, 0); - } - explicit TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - return o; - } -}; - -inline flatbuffers::Offset CreateType( - flatbuffers::FlatBufferBuilder &_fbb, - reflection::BaseType base_type = reflection::None, - reflection::BaseType element = reflection::None, - int32_t index = -1, - uint16_t fixed_length = 0) { - TypeBuilder builder_(_fbb); - builder_.add_index(index); - builder_.add_fixed_length(fixed_length); - builder_.add_element(element); - builder_.add_base_type(base_type); - return builder_.Finish(); -} - -struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef KeyValueBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_KEY = 4, - VT_VALUE = 6 - }; - const flatbuffers::String *key() const { - return GetPointer(VT_KEY); - } - bool KeyCompareLessThan(const KeyValue *o) const { - return *key() < *o->key(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(key()->c_str(), val); - } - const flatbuffers::String *value() const { - return GetPointer(VT_VALUE); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_KEY) && - verifier.VerifyString(key()) && - VerifyOffset(verifier, VT_VALUE) && - verifier.VerifyString(value()) && - verifier.EndTable(); - } -}; - -struct KeyValueBuilder { - typedef KeyValue Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_key(flatbuffers::Offset key) { - fbb_.AddOffset(KeyValue::VT_KEY, key); - } - void add_value(flatbuffers::Offset value) { - fbb_.AddOffset(KeyValue::VT_VALUE, value); - } - explicit KeyValueBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - fbb_.Required(o, KeyValue::VT_KEY); - return o; - } -}; - -inline flatbuffers::Offset CreateKeyValue( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset key = 0, - flatbuffers::Offset value = 0) { - KeyValueBuilder builder_(_fbb); - builder_.add_value(value); - builder_.add_key(key); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateKeyValueDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *key = nullptr, - const char *value = nullptr) { - auto key__ = key ? _fbb.CreateString(key) : 0; - auto value__ = value ? _fbb.CreateString(value) : 0; - return reflection::CreateKeyValue( - _fbb, - key__, - value__); -} - -struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef EnumValBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_VALUE = 6, - VT_OBJECT = 8, - VT_UNION_TYPE = 10, - VT_DOCUMENTATION = 12 - }; - const flatbuffers::String *name() const { - return GetPointer(VT_NAME); - } - int64_t value() const { - return GetField(VT_VALUE, 0); - } - bool KeyCompareLessThan(const EnumVal *o) const { - return value() < o->value(); - } - int KeyCompareWithValue(int64_t val) const { - return static_cast(value() > val) - static_cast(value() < val); - } - const reflection::Object *object() const { - return GetPointer(VT_OBJECT); - } - const reflection::Type *union_type() const { - return GetPointer(VT_UNION_TYPE); - } - const flatbuffers::Vector> *documentation() const { - return GetPointer> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyField(verifier, VT_VALUE) && - VerifyOffset(verifier, VT_OBJECT) && - verifier.VerifyTable(object()) && - VerifyOffset(verifier, VT_UNION_TYPE) && - verifier.VerifyTable(union_type()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct EnumValBuilder { - typedef EnumVal Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset name) { - fbb_.AddOffset(EnumVal::VT_NAME, name); - } - void add_value(int64_t value) { - fbb_.AddElement(EnumVal::VT_VALUE, value, 0); - } - void add_object(flatbuffers::Offset object) { - fbb_.AddOffset(EnumVal::VT_OBJECT, object); - } - void add_union_type(flatbuffers::Offset union_type) { - fbb_.AddOffset(EnumVal::VT_UNION_TYPE, union_type); - } - void add_documentation(flatbuffers::Offset>> documentation) { - fbb_.AddOffset(EnumVal::VT_DOCUMENTATION, documentation); - } - explicit EnumValBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - fbb_.Required(o, EnumVal::VT_NAME); - return o; - } -}; - -inline flatbuffers::Offset CreateEnumVal( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset name = 0, - int64_t value = 0, - flatbuffers::Offset object = 0, - flatbuffers::Offset union_type = 0, - flatbuffers::Offset>> documentation = 0) { - EnumValBuilder builder_(_fbb); - builder_.add_value(value); - builder_.add_documentation(documentation); - builder_.add_union_type(union_type); - builder_.add_object(object); - builder_.add_name(name); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateEnumValDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - int64_t value = 0, - flatbuffers::Offset object = 0, - flatbuffers::Offset union_type = 0, - const std::vector> *documentation = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto documentation__ = documentation ? _fbb.CreateVector>(*documentation) : 0; - return reflection::CreateEnumVal( - _fbb, - name__, - value, - object, - union_type, - documentation__); -} - -struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef EnumBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_VALUES = 6, - VT_IS_UNION = 8, - VT_UNDERLYING_TYPE = 10, - VT_ATTRIBUTES = 12, - VT_DOCUMENTATION = 14 - }; - const flatbuffers::String *name() const { - return GetPointer(VT_NAME); - } - bool KeyCompareLessThan(const Enum *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } - const flatbuffers::Vector> *values() const { - return GetPointer> *>(VT_VALUES); - } - bool is_union() const { - return GetField(VT_IS_UNION, 0) != 0; - } - const reflection::Type *underlying_type() const { - return GetPointer(VT_UNDERLYING_TYPE); - } - const flatbuffers::Vector> *attributes() const { - return GetPointer> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector> *documentation() const { - return GetPointer> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_VALUES) && - verifier.VerifyVector(values()) && - verifier.VerifyVectorOfTables(values()) && - VerifyField(verifier, VT_IS_UNION) && - VerifyOffsetRequired(verifier, VT_UNDERLYING_TYPE) && - verifier.VerifyTable(underlying_type()) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct EnumBuilder { - typedef Enum Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset name) { - fbb_.AddOffset(Enum::VT_NAME, name); - } - void add_values(flatbuffers::Offset>> values) { - fbb_.AddOffset(Enum::VT_VALUES, values); - } - void add_is_union(bool is_union) { - fbb_.AddElement(Enum::VT_IS_UNION, static_cast(is_union), 0); - } - void add_underlying_type(flatbuffers::Offset underlying_type) { - fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type); - } - void add_attributes(flatbuffers::Offset>> attributes) { - fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset>> documentation) { - fbb_.AddOffset(Enum::VT_DOCUMENTATION, documentation); - } - explicit EnumBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - fbb_.Required(o, Enum::VT_NAME); - fbb_.Required(o, Enum::VT_VALUES); - fbb_.Required(o, Enum::VT_UNDERLYING_TYPE); - return o; - } -}; - -inline flatbuffers::Offset CreateEnum( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset name = 0, - flatbuffers::Offset>> values = 0, - bool is_union = false, - flatbuffers::Offset underlying_type = 0, - flatbuffers::Offset>> attributes = 0, - flatbuffers::Offset>> documentation = 0) { - EnumBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_underlying_type(underlying_type); - builder_.add_values(values); - builder_.add_name(name); - builder_.add_is_union(is_union); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateEnumDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - std::vector> *values = nullptr, - bool is_union = false, - flatbuffers::Offset underlying_type = 0, - std::vector> *attributes = nullptr, - const std::vector> *documentation = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto values__ = values ? _fbb.CreateVectorOfSortedTables(values) : 0; - auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables(attributes) : 0; - auto documentation__ = documentation ? _fbb.CreateVector>(*documentation) : 0; - return reflection::CreateEnum( - _fbb, - name__, - values__, - is_union, - underlying_type, - attributes__, - documentation__); -} - -struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef FieldBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_TYPE = 6, - VT_ID = 8, - VT_OFFSET = 10, - VT_DEFAULT_INTEGER = 12, - VT_DEFAULT_REAL = 14, - VT_DEPRECATED = 16, - VT_REQUIRED = 18, - VT_KEY = 20, - VT_ATTRIBUTES = 22, - VT_DOCUMENTATION = 24 - }; - const flatbuffers::String *name() const { - return GetPointer(VT_NAME); - } - bool KeyCompareLessThan(const Field *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } - const reflection::Type *type() const { - return GetPointer(VT_TYPE); - } - uint16_t id() const { - return GetField(VT_ID, 0); - } - uint16_t offset() const { - return GetField(VT_OFFSET, 0); - } - int64_t default_integer() const { - return GetField(VT_DEFAULT_INTEGER, 0); - } - double default_real() const { - return GetField(VT_DEFAULT_REAL, 0.0); - } - bool deprecated() const { - return GetField(VT_DEPRECATED, 0) != 0; - } - bool required() const { - return GetField(VT_REQUIRED, 0) != 0; - } - bool key() const { - return GetField(VT_KEY, 0) != 0; - } - const flatbuffers::Vector> *attributes() const { - return GetPointer> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector> *documentation() const { - return GetPointer> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_TYPE) && - verifier.VerifyTable(type()) && - VerifyField(verifier, VT_ID) && - VerifyField(verifier, VT_OFFSET) && - VerifyField(verifier, VT_DEFAULT_INTEGER) && - VerifyField(verifier, VT_DEFAULT_REAL) && - VerifyField(verifier, VT_DEPRECATED) && - VerifyField(verifier, VT_REQUIRED) && - VerifyField(verifier, VT_KEY) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct FieldBuilder { - typedef Field Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset name) { - fbb_.AddOffset(Field::VT_NAME, name); - } - void add_type(flatbuffers::Offset type) { - fbb_.AddOffset(Field::VT_TYPE, type); - } - void add_id(uint16_t id) { - fbb_.AddElement(Field::VT_ID, id, 0); - } - void add_offset(uint16_t offset) { - fbb_.AddElement(Field::VT_OFFSET, offset, 0); - } - void add_default_integer(int64_t default_integer) { - fbb_.AddElement(Field::VT_DEFAULT_INTEGER, default_integer, 0); - } - void add_default_real(double default_real) { - fbb_.AddElement(Field::VT_DEFAULT_REAL, default_real, 0.0); - } - void add_deprecated(bool deprecated) { - fbb_.AddElement(Field::VT_DEPRECATED, static_cast(deprecated), 0); - } - void add_required(bool required) { - fbb_.AddElement(Field::VT_REQUIRED, static_cast(required), 0); - } - void add_key(bool key) { - fbb_.AddElement(Field::VT_KEY, static_cast(key), 0); - } - void add_attributes(flatbuffers::Offset>> attributes) { - fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset>> documentation) { - fbb_.AddOffset(Field::VT_DOCUMENTATION, documentation); - } - explicit FieldBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - fbb_.Required(o, Field::VT_NAME); - fbb_.Required(o, Field::VT_TYPE); - return o; - } -}; - -inline flatbuffers::Offset CreateField( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset name = 0, - flatbuffers::Offset type = 0, - uint16_t id = 0, - uint16_t offset = 0, - int64_t default_integer = 0, - double default_real = 0.0, - bool deprecated = false, - bool required = false, - bool key = false, - flatbuffers::Offset>> attributes = 0, - flatbuffers::Offset>> documentation = 0) { - FieldBuilder builder_(_fbb); - builder_.add_default_real(default_real); - builder_.add_default_integer(default_integer); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_type(type); - builder_.add_name(name); - builder_.add_offset(offset); - builder_.add_id(id); - builder_.add_key(key); - builder_.add_required(required); - builder_.add_deprecated(deprecated); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateFieldDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - flatbuffers::Offset type = 0, - uint16_t id = 0, - uint16_t offset = 0, - int64_t default_integer = 0, - double default_real = 0.0, - bool deprecated = false, - bool required = false, - bool key = false, - std::vector> *attributes = nullptr, - const std::vector> *documentation = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables(attributes) : 0; - auto documentation__ = documentation ? _fbb.CreateVector>(*documentation) : 0; - return reflection::CreateField( - _fbb, - name__, - type, - id, - offset, - default_integer, - default_real, - deprecated, - required, - key, - attributes__, - documentation__); -} - -struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef ObjectBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_FIELDS = 6, - VT_IS_STRUCT = 8, - VT_MINALIGN = 10, - VT_BYTESIZE = 12, - VT_ATTRIBUTES = 14, - VT_DOCUMENTATION = 16 - }; - const flatbuffers::String *name() const { - return GetPointer(VT_NAME); - } - bool KeyCompareLessThan(const Object *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } - const flatbuffers::Vector> *fields() const { - return GetPointer> *>(VT_FIELDS); - } - bool is_struct() const { - return GetField(VT_IS_STRUCT, 0) != 0; - } - int32_t minalign() const { - return GetField(VT_MINALIGN, 0); - } - int32_t bytesize() const { - return GetField(VT_BYTESIZE, 0); - } - const flatbuffers::Vector> *attributes() const { - return GetPointer> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector> *documentation() const { - return GetPointer> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_FIELDS) && - verifier.VerifyVector(fields()) && - verifier.VerifyVectorOfTables(fields()) && - VerifyField(verifier, VT_IS_STRUCT) && - VerifyField(verifier, VT_MINALIGN) && - VerifyField(verifier, VT_BYTESIZE) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct ObjectBuilder { - typedef Object Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset name) { - fbb_.AddOffset(Object::VT_NAME, name); - } - void add_fields(flatbuffers::Offset>> fields) { - fbb_.AddOffset(Object::VT_FIELDS, fields); - } - void add_is_struct(bool is_struct) { - fbb_.AddElement(Object::VT_IS_STRUCT, static_cast(is_struct), 0); - } - void add_minalign(int32_t minalign) { - fbb_.AddElement(Object::VT_MINALIGN, minalign, 0); - } - void add_bytesize(int32_t bytesize) { - fbb_.AddElement(Object::VT_BYTESIZE, bytesize, 0); - } - void add_attributes(flatbuffers::Offset>> attributes) { - fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset>> documentation) { - fbb_.AddOffset(Object::VT_DOCUMENTATION, documentation); - } - explicit ObjectBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - fbb_.Required(o, Object::VT_NAME); - fbb_.Required(o, Object::VT_FIELDS); - return o; - } -}; - -inline flatbuffers::Offset CreateObject( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset name = 0, - flatbuffers::Offset>> fields = 0, - bool is_struct = false, - int32_t minalign = 0, - int32_t bytesize = 0, - flatbuffers::Offset>> attributes = 0, - flatbuffers::Offset>> documentation = 0) { - ObjectBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_bytesize(bytesize); - builder_.add_minalign(minalign); - builder_.add_fields(fields); - builder_.add_name(name); - builder_.add_is_struct(is_struct); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateObjectDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - std::vector> *fields = nullptr, - bool is_struct = false, - int32_t minalign = 0, - int32_t bytesize = 0, - std::vector> *attributes = nullptr, - const std::vector> *documentation = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto fields__ = fields ? _fbb.CreateVectorOfSortedTables(fields) : 0; - auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables(attributes) : 0; - auto documentation__ = documentation ? _fbb.CreateVector>(*documentation) : 0; - return reflection::CreateObject( - _fbb, - name__, - fields__, - is_struct, - minalign, - bytesize, - attributes__, - documentation__); -} - -struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef RPCCallBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_REQUEST = 6, - VT_RESPONSE = 8, - VT_ATTRIBUTES = 10, - VT_DOCUMENTATION = 12 - }; - const flatbuffers::String *name() const { - return GetPointer(VT_NAME); - } - bool KeyCompareLessThan(const RPCCall *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } - const reflection::Object *request() const { - return GetPointer(VT_REQUEST); - } - const reflection::Object *response() const { - return GetPointer(VT_RESPONSE); - } - const flatbuffers::Vector> *attributes() const { - return GetPointer> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector> *documentation() const { - return GetPointer> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffsetRequired(verifier, VT_REQUEST) && - verifier.VerifyTable(request()) && - VerifyOffsetRequired(verifier, VT_RESPONSE) && - verifier.VerifyTable(response()) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct RPCCallBuilder { - typedef RPCCall Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset name) { - fbb_.AddOffset(RPCCall::VT_NAME, name); - } - void add_request(flatbuffers::Offset request) { - fbb_.AddOffset(RPCCall::VT_REQUEST, request); - } - void add_response(flatbuffers::Offset response) { - fbb_.AddOffset(RPCCall::VT_RESPONSE, response); - } - void add_attributes(flatbuffers::Offset>> attributes) { - fbb_.AddOffset(RPCCall::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset>> documentation) { - fbb_.AddOffset(RPCCall::VT_DOCUMENTATION, documentation); - } - explicit RPCCallBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - fbb_.Required(o, RPCCall::VT_NAME); - fbb_.Required(o, RPCCall::VT_REQUEST); - fbb_.Required(o, RPCCall::VT_RESPONSE); - return o; - } -}; - -inline flatbuffers::Offset CreateRPCCall( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset name = 0, - flatbuffers::Offset request = 0, - flatbuffers::Offset response = 0, - flatbuffers::Offset>> attributes = 0, - flatbuffers::Offset>> documentation = 0) { - RPCCallBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_response(response); - builder_.add_request(request); - builder_.add_name(name); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateRPCCallDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - flatbuffers::Offset request = 0, - flatbuffers::Offset response = 0, - std::vector> *attributes = nullptr, - const std::vector> *documentation = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables(attributes) : 0; - auto documentation__ = documentation ? _fbb.CreateVector>(*documentation) : 0; - return reflection::CreateRPCCall( - _fbb, - name__, - request, - response, - attributes__, - documentation__); -} - -struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef ServiceBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_CALLS = 6, - VT_ATTRIBUTES = 8, - VT_DOCUMENTATION = 10 - }; - const flatbuffers::String *name() const { - return GetPointer(VT_NAME); - } - bool KeyCompareLessThan(const Service *o) const { - return *name() < *o->name(); - } - int KeyCompareWithValue(const char *val) const { - return strcmp(name()->c_str(), val); - } - const flatbuffers::Vector> *calls() const { - return GetPointer> *>(VT_CALLS); - } - const flatbuffers::Vector> *attributes() const { - return GetPointer> *>(VT_ATTRIBUTES); - } - const flatbuffers::Vector> *documentation() const { - return GetPointer> *>(VT_DOCUMENTATION); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffset(verifier, VT_CALLS) && - verifier.VerifyVector(calls()) && - verifier.VerifyVectorOfTables(calls()) && - VerifyOffset(verifier, VT_ATTRIBUTES) && - verifier.VerifyVector(attributes()) && - verifier.VerifyVectorOfTables(attributes()) && - VerifyOffset(verifier, VT_DOCUMENTATION) && - verifier.VerifyVector(documentation()) && - verifier.VerifyVectorOfStrings(documentation()) && - verifier.EndTable(); - } -}; - -struct ServiceBuilder { - typedef Service Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_name(flatbuffers::Offset name) { - fbb_.AddOffset(Service::VT_NAME, name); - } - void add_calls(flatbuffers::Offset>> calls) { - fbb_.AddOffset(Service::VT_CALLS, calls); - } - void add_attributes(flatbuffers::Offset>> attributes) { - fbb_.AddOffset(Service::VT_ATTRIBUTES, attributes); - } - void add_documentation(flatbuffers::Offset>> documentation) { - fbb_.AddOffset(Service::VT_DOCUMENTATION, documentation); - } - explicit ServiceBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - fbb_.Required(o, Service::VT_NAME); - return o; - } -}; - -inline flatbuffers::Offset CreateService( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset name = 0, - flatbuffers::Offset>> calls = 0, - flatbuffers::Offset>> attributes = 0, - flatbuffers::Offset>> documentation = 0) { - ServiceBuilder builder_(_fbb); - builder_.add_documentation(documentation); - builder_.add_attributes(attributes); - builder_.add_calls(calls); - builder_.add_name(name); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateServiceDirect( - flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - std::vector> *calls = nullptr, - std::vector> *attributes = nullptr, - const std::vector> *documentation = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto calls__ = calls ? _fbb.CreateVectorOfSortedTables(calls) : 0; - auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables(attributes) : 0; - auto documentation__ = documentation ? _fbb.CreateVector>(*documentation) : 0; - return reflection::CreateService( - _fbb, - name__, - calls__, - attributes__, - documentation__); -} - -struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef SchemaBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_OBJECTS = 4, - VT_ENUMS = 6, - VT_FILE_IDENT = 8, - VT_FILE_EXT = 10, - VT_ROOT_TABLE = 12, - VT_SERVICES = 14 - }; - const flatbuffers::Vector> *objects() const { - return GetPointer> *>(VT_OBJECTS); - } - const flatbuffers::Vector> *enums() const { - return GetPointer> *>(VT_ENUMS); - } - const flatbuffers::String *file_ident() const { - return GetPointer(VT_FILE_IDENT); - } - const flatbuffers::String *file_ext() const { - return GetPointer(VT_FILE_EXT); - } - const reflection::Object *root_table() const { - return GetPointer(VT_ROOT_TABLE); - } - const flatbuffers::Vector> *services() const { - return GetPointer> *>(VT_SERVICES); - } - bool Verify(flatbuffers::Verifier &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_OBJECTS) && - verifier.VerifyVector(objects()) && - verifier.VerifyVectorOfTables(objects()) && - VerifyOffsetRequired(verifier, VT_ENUMS) && - verifier.VerifyVector(enums()) && - verifier.VerifyVectorOfTables(enums()) && - VerifyOffset(verifier, VT_FILE_IDENT) && - verifier.VerifyString(file_ident()) && - VerifyOffset(verifier, VT_FILE_EXT) && - verifier.VerifyString(file_ext()) && - VerifyOffset(verifier, VT_ROOT_TABLE) && - verifier.VerifyTable(root_table()) && - VerifyOffset(verifier, VT_SERVICES) && - verifier.VerifyVector(services()) && - verifier.VerifyVectorOfTables(services()) && - verifier.EndTable(); - } -}; - -struct SchemaBuilder { - typedef Schema Table; - flatbuffers::FlatBufferBuilder &fbb_; - flatbuffers::uoffset_t start_; - void add_objects(flatbuffers::Offset>> objects) { - fbb_.AddOffset(Schema::VT_OBJECTS, objects); - } - void add_enums(flatbuffers::Offset>> enums) { - fbb_.AddOffset(Schema::VT_ENUMS, enums); - } - void add_file_ident(flatbuffers::Offset file_ident) { - fbb_.AddOffset(Schema::VT_FILE_IDENT, file_ident); - } - void add_file_ext(flatbuffers::Offset file_ext) { - fbb_.AddOffset(Schema::VT_FILE_EXT, file_ext); - } - void add_root_table(flatbuffers::Offset root_table) { - fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table); - } - void add_services(flatbuffers::Offset>> services) { - fbb_.AddOffset(Schema::VT_SERVICES, services); - } - explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = flatbuffers::Offset(end); - fbb_.Required(o, Schema::VT_OBJECTS); - fbb_.Required(o, Schema::VT_ENUMS); - return o; - } -}; - -inline flatbuffers::Offset CreateSchema( - flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset>> objects = 0, - flatbuffers::Offset>> enums = 0, - flatbuffers::Offset file_ident = 0, - flatbuffers::Offset file_ext = 0, - flatbuffers::Offset root_table = 0, - flatbuffers::Offset>> services = 0) { - SchemaBuilder builder_(_fbb); - builder_.add_services(services); - builder_.add_root_table(root_table); - builder_.add_file_ext(file_ext); - builder_.add_file_ident(file_ident); - builder_.add_enums(enums); - builder_.add_objects(objects); - return builder_.Finish(); -} - -inline flatbuffers::Offset CreateSchemaDirect( - flatbuffers::FlatBufferBuilder &_fbb, - std::vector> *objects = nullptr, - std::vector> *enums = nullptr, - const char *file_ident = nullptr, - const char *file_ext = nullptr, - flatbuffers::Offset root_table = 0, - std::vector> *services = nullptr) { - auto objects__ = objects ? _fbb.CreateVectorOfSortedTables(objects) : 0; - auto enums__ = enums ? _fbb.CreateVectorOfSortedTables(enums) : 0; - auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0; - auto file_ext__ = file_ext ? _fbb.CreateString(file_ext) : 0; - auto services__ = services ? _fbb.CreateVectorOfSortedTables(services) : 0; - return reflection::CreateSchema( - _fbb, - objects__, - enums__, - file_ident__, - file_ext__, - root_table, - services__); -} - -inline const reflection::Schema *GetSchema(const void *buf) { - return flatbuffers::GetRoot(buf); -} - -inline const reflection::Schema *GetSizePrefixedSchema(const void *buf) { - return flatbuffers::GetSizePrefixedRoot(buf); -} - -inline const char *SchemaIdentifier() { - return "BFBS"; -} - -inline bool SchemaBufferHasIdentifier(const void *buf) { - return flatbuffers::BufferHasIdentifier( - buf, SchemaIdentifier()); -} - -inline bool VerifySchemaBuffer( - flatbuffers::Verifier &verifier) { - return verifier.VerifyBuffer(SchemaIdentifier()); -} - -inline bool VerifySizePrefixedSchemaBuffer( - flatbuffers::Verifier &verifier) { - return verifier.VerifySizePrefixedBuffer(SchemaIdentifier()); -} - -inline const char *SchemaExtension() { - return "bfbs"; -} - -inline void FinishSchemaBuffer( - flatbuffers::FlatBufferBuilder &fbb, - flatbuffers::Offset root) { - fbb.Finish(root, SchemaIdentifier()); -} - -inline void FinishSizePrefixedSchemaBuffer( - flatbuffers::FlatBufferBuilder &fbb, - flatbuffers::Offset root) { - fbb.FinishSizePrefixed(root, SchemaIdentifier()); -} - -} // namespace reflection - -#endif // FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_ diff --git a/daemon/src/External/include/flatbuffers/registry.h b/daemon/src/External/include/flatbuffers/registry.h deleted file mode 100644 index 9ea425b3..00000000 --- a/daemon/src/External/include/flatbuffers/registry.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_REGISTRY_H_ -#define FLATBUFFERS_REGISTRY_H_ - -#include "flatbuffers/idl.h" - -namespace flatbuffers { - -// Convenience class to easily parse or generate text for arbitrary FlatBuffers. -// Simply pre-populate it with all schema filenames that may be in use, and -// This class will look them up using the file_identifier declared in the -// schema. -class Registry { - public: - // Call this for all schemas that may be in use. The identifier has - // a function in the generated code, e.g. MonsterIdentifier(). - void Register(const char *file_identifier, const char *schema_path) { - Schema schema; - schema.path_ = schema_path; - schemas_[file_identifier] = schema; - } - - // Generate text from an arbitrary FlatBuffer by looking up its - // file_identifier in the registry. - bool FlatBufferToText(const uint8_t *flatbuf, size_t len, std::string *dest) { - // Get the identifier out of the buffer. - // If the buffer is truncated, exit. - if (len < sizeof(uoffset_t) + FlatBufferBuilder::kFileIdentifierLength) { - lasterror_ = "buffer truncated"; - return false; - } - std::string ident( - reinterpret_cast(flatbuf) + sizeof(uoffset_t), - FlatBufferBuilder::kFileIdentifierLength); - // Load and parse the schema. - Parser parser; - if (!LoadSchema(ident, &parser)) return false; - // Now we're ready to generate text. - if (!GenerateText(parser, flatbuf, dest)) { - lasterror_ = "unable to generate text for FlatBuffer binary"; - return false; - } - return true; - } - - // Converts a binary buffer to text using one of the schemas in the registry, - // use the file_identifier to indicate which. - // If DetachedBuffer::data() is null then parsing failed. - DetachedBuffer TextToFlatBuffer(const char *text, - const char *file_identifier) { - // Load and parse the schema. - Parser parser; - if (!LoadSchema(file_identifier, &parser)) return DetachedBuffer(); - // Parse the text. - if (!parser.Parse(text)) { - lasterror_ = parser.error_; - return DetachedBuffer(); - } - // We have a valid FlatBuffer. Detach it from the builder and return. - return parser.builder_.Release(); - } - - // Modify any parsing / output options used by the other functions. - void SetOptions(const IDLOptions &opts) { opts_ = opts; } - - // If schemas used contain include statements, call this function for every - // directory the parser should search them for. - void AddIncludeDirectory(const char *path) { include_paths_.push_back(path); } - - // Returns a human readable error if any of the above functions fail. - const std::string &GetLastError() { return lasterror_; } - - private: - bool LoadSchema(const std::string &ident, Parser *parser) { - // Find the schema, if not, exit. - auto it = schemas_.find(ident); - if (it == schemas_.end()) { - // Don't attach the identifier, since it may not be human readable. - lasterror_ = "identifier for this buffer not in the registry"; - return false; - } - auto &schema = it->second; - // Load the schema from disk. If not, exit. - std::string schematext; - if (!LoadFile(schema.path_.c_str(), false, &schematext)) { - lasterror_ = "could not load schema: " + schema.path_; - return false; - } - // Parse schema. - parser->opts = opts_; - if (!parser->Parse(schematext.c_str(), vector_data(include_paths_), - schema.path_.c_str())) { - lasterror_ = parser->error_; - return false; - } - return true; - } - - struct Schema { - std::string path_; - // TODO(wvo) optionally cache schema file or parsed schema here. - }; - - std::string lasterror_; - IDLOptions opts_; - std::vector include_paths_; - std::map schemas_; -}; - -} // namespace flatbuffers - -#endif // FLATBUFFERS_REGISTRY_H_ diff --git a/daemon/src/External/include/flatbuffers/stl_emulation.h b/daemon/src/External/include/flatbuffers/stl_emulation.h deleted file mode 100644 index d7d655ef..00000000 --- a/daemon/src/External/include/flatbuffers/stl_emulation.h +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright 2017 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_STL_EMULATION_H_ -#define FLATBUFFERS_STL_EMULATION_H_ - -// clang-format off - -#include -#include -#include -#include -#include - -#if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL) - #define FLATBUFFERS_CPP98_STL -#endif // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL) - -#if defined(FLATBUFFERS_CPP98_STL) - #include -#endif // defined(FLATBUFFERS_CPP98_STL) - -// Check if we can use template aliases -// Not possible if Microsoft Compiler before 2012 -// Possible is the language feature __cpp_alias_templates is defined well -// Or possible if the C++ std is C+11 or newer -#if (defined(_MSC_VER) && _MSC_VER > 1700 /* MSVC2012 */) \ - || (defined(__cpp_alias_templates) && __cpp_alias_templates >= 200704) \ - || (defined(__cplusplus) && __cplusplus >= 201103L) - #define FLATBUFFERS_TEMPLATES_ALIASES -#endif - -// This header provides backwards compatibility for C++98 STLs like stlport. -namespace flatbuffers { - -// Retrieve ::back() from a string in a way that is compatible with pre C++11 -// STLs (e.g stlport). -inline char& string_back(std::string &value) { - return value[value.length() - 1]; -} - -inline char string_back(const std::string &value) { - return value[value.length() - 1]; -} - -// Helper method that retrieves ::data() from a vector in a way that is -// compatible with pre C++11 STLs (e.g stlport). -template inline T *vector_data(std::vector &vector) { - // In some debug environments, operator[] does bounds checking, so &vector[0] - // can't be used. - return vector.empty() ? nullptr : &vector[0]; -} - -template inline const T *vector_data( - const std::vector &vector) { - return vector.empty() ? nullptr : &vector[0]; -} - -template -inline void vector_emplace_back(std::vector *vector, V &&data) { - #if defined(FLATBUFFERS_CPP98_STL) - vector->push_back(data); - #else - vector->emplace_back(std::forward(data)); - #endif // defined(FLATBUFFERS_CPP98_STL) -} - -#ifndef FLATBUFFERS_CPP98_STL - #if defined(FLATBUFFERS_TEMPLATES_ALIASES) - template - using numeric_limits = std::numeric_limits; - #else - template class numeric_limits : - public std::numeric_limits {}; - #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) -#else - template class numeric_limits : - public std::numeric_limits { - public: - // Android NDK fix. - static T lowest() { - return std::numeric_limits::min(); - } - }; - - template <> class numeric_limits : - public std::numeric_limits { - public: - static float lowest() { return -FLT_MAX; } - }; - - template <> class numeric_limits : - public std::numeric_limits { - public: - static double lowest() { return -DBL_MAX; } - }; - - template <> class numeric_limits { - public: - static unsigned long long min() { return 0ULL; } - static unsigned long long max() { return ~0ULL; } - static unsigned long long lowest() { - return numeric_limits::min(); - } - }; - - template <> class numeric_limits { - public: - static long long min() { - return static_cast(1ULL << ((sizeof(long long) << 3) - 1)); - } - static long long max() { - return static_cast( - (1ULL << ((sizeof(long long) << 3) - 1)) - 1); - } - static long long lowest() { - return numeric_limits::min(); - } - }; -#endif // FLATBUFFERS_CPP98_STL - -#if defined(FLATBUFFERS_TEMPLATES_ALIASES) - #ifndef FLATBUFFERS_CPP98_STL - template using is_scalar = std::is_scalar; - template using is_same = std::is_same; - template using is_floating_point = std::is_floating_point; - template using is_unsigned = std::is_unsigned; - template using is_enum = std::is_enum; - template using make_unsigned = std::make_unsigned; - template - using conditional = std::conditional; - template - using integral_constant = std::integral_constant; - #else - // Map C++ TR1 templates defined by stlport. - template using is_scalar = std::tr1::is_scalar; - template using is_same = std::tr1::is_same; - template using is_floating_point = - std::tr1::is_floating_point; - template using is_unsigned = std::tr1::is_unsigned; - template using is_enum = std::tr1::is_enum; - // Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned. - template struct make_unsigned { - static_assert(is_unsigned::value, "Specialization not implemented!"); - using type = T; - }; - template<> struct make_unsigned { using type = unsigned char; }; - template<> struct make_unsigned { using type = unsigned short; }; - template<> struct make_unsigned { using type = unsigned int; }; - template<> struct make_unsigned { using type = unsigned long; }; - template<> - struct make_unsigned { using type = unsigned long long; }; - template - using conditional = std::tr1::conditional; - template - using integral_constant = std::tr1::integral_constant; - #endif // !FLATBUFFERS_CPP98_STL -#else - // MSVC 2010 doesn't support C++11 aliases. - template struct is_scalar : public std::is_scalar {}; - template struct is_same : public std::is_same {}; - template struct is_floating_point : - public std::is_floating_point {}; - template struct is_unsigned : public std::is_unsigned {}; - template struct is_enum : public std::is_enum {}; - template struct make_unsigned : public std::make_unsigned {}; - template - struct conditional : public std::conditional {}; - template - struct integral_constant : public std::integral_constant {}; -#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) - -#ifndef FLATBUFFERS_CPP98_STL - #if defined(FLATBUFFERS_TEMPLATES_ALIASES) - template using unique_ptr = std::unique_ptr; - #else - // MSVC 2010 doesn't support C++11 aliases. - // We're manually "aliasing" the class here as we want to bring unique_ptr - // into the flatbuffers namespace. We have unique_ptr in the flatbuffers - // namespace we have a completely independent implementation (see below) - // for C++98 STL implementations. - template class unique_ptr : public std::unique_ptr { - public: - unique_ptr() {} - explicit unique_ptr(T* p) : std::unique_ptr(p) {} - unique_ptr(std::unique_ptr&& u) { *this = std::move(u); } - unique_ptr(unique_ptr&& u) { *this = std::move(u); } - unique_ptr& operator=(std::unique_ptr&& u) { - std::unique_ptr::reset(u.release()); - return *this; - } - unique_ptr& operator=(unique_ptr&& u) { - std::unique_ptr::reset(u.release()); - return *this; - } - unique_ptr& operator=(T* p) { - return std::unique_ptr::operator=(p); - } - }; - #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES) -#else - // Very limited implementation of unique_ptr. - // This is provided simply to allow the C++ code generated from the default - // settings to function in C++98 environments with no modifications. - template class unique_ptr { - public: - typedef T element_type; - - unique_ptr() : ptr_(nullptr) {} - explicit unique_ptr(T* p) : ptr_(p) {} - unique_ptr(unique_ptr&& u) : ptr_(nullptr) { reset(u.release()); } - unique_ptr(const unique_ptr& u) : ptr_(nullptr) { - reset(const_cast(&u)->release()); - } - ~unique_ptr() { reset(); } - - unique_ptr& operator=(const unique_ptr& u) { - reset(const_cast(&u)->release()); - return *this; - } - - unique_ptr& operator=(unique_ptr&& u) { - reset(u.release()); - return *this; - } - - unique_ptr& operator=(T* p) { - reset(p); - return *this; - } - - const T& operator*() const { return *ptr_; } - T* operator->() const { return ptr_; } - T* get() const noexcept { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - // modifiers - T* release() { - T* value = ptr_; - ptr_ = nullptr; - return value; - } - - void reset(T* p = nullptr) { - T* value = ptr_; - ptr_ = p; - if (value) delete value; - } - - void swap(unique_ptr& u) { - T* temp_ptr = ptr_; - ptr_ = u.ptr_; - u.ptr_ = temp_ptr; - } - - private: - T* ptr_; - }; - - template bool operator==(const unique_ptr& x, - const unique_ptr& y) { - return x.get() == y.get(); - } - - template bool operator==(const unique_ptr& x, - const D* y) { - return static_cast(x.get()) == y; - } - - template bool operator==(const unique_ptr& x, intptr_t y) { - return reinterpret_cast(x.get()) == y; - } - - template bool operator!=(const unique_ptr& x, decltype(nullptr)) { - return !!x; - } - - template bool operator!=(decltype(nullptr), const unique_ptr& x) { - return !!x; - } - - template bool operator==(const unique_ptr& x, decltype(nullptr)) { - return !x; - } - - template bool operator==(decltype(nullptr), const unique_ptr& x) { - return !x; - } - -#endif // !FLATBUFFERS_CPP98_STL - -} // namespace flatbuffers - -#endif // FLATBUFFERS_STL_EMULATION_H_ diff --git a/daemon/src/External/include/flatbuffers/util.h b/daemon/src/External/include/flatbuffers/util.h deleted file mode 100644 index b6340a2a..00000000 --- a/daemon/src/External/include/flatbuffers/util.h +++ /dev/null @@ -1,683 +0,0 @@ -/* - * Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLATBUFFERS_UTIL_H_ -#define FLATBUFFERS_UTIL_H_ - -#include - -#include "flatbuffers/base.h" - -#ifndef FLATBUFFERS_PREFER_PRINTF -# include -#else // FLATBUFFERS_PREFER_PRINTF -# include -# include -#endif // FLATBUFFERS_PREFER_PRINTF - -#include -#include - -namespace flatbuffers { - -// @locale-independent functions for ASCII characters set. - -// Fast checking that character lies in closed range: [a <= x <= b] -// using one compare (conditional branch) operator. -inline bool check_ascii_range(char x, char a, char b) { - FLATBUFFERS_ASSERT(a <= b); - // (Hacker's Delight): `a <= x <= b` <=> `(x-a) <={u} (b-a)`. - // The x, a, b will be promoted to int and subtracted without overflow. - return static_cast(x - a) <= static_cast(b - a); -} - -// Case-insensitive isalpha -inline bool is_alpha(char c) { - // ASCII only: alpha to upper case => reset bit 0x20 (~0x20 = 0xDF). - return check_ascii_range(c & 0xDF, 'a' & 0xDF, 'z' & 0xDF); -} - -// Check (case-insensitive) that `c` is equal to alpha. -inline bool is_alpha_char(char c, char alpha) { - FLATBUFFERS_ASSERT(is_alpha(alpha)); - // ASCII only: alpha to upper case => reset bit 0x20 (~0x20 = 0xDF). - return ((c & 0xDF) == (alpha & 0xDF)); -} - -// https://en.cppreference.com/w/cpp/string/byte/isxdigit -// isdigit and isxdigit are the only standard narrow character classification -// functions that are not affected by the currently installed C locale. although -// some implementations (e.g. Microsoft in 1252 codepage) may classify -// additional single-byte characters as digits. -inline bool is_digit(char c) { return check_ascii_range(c, '0', '9'); } - -inline bool is_xdigit(char c) { - // Replace by look-up table. - return is_digit(c) || check_ascii_range(c & 0xDF, 'a' & 0xDF, 'f' & 0xDF); -} - -// Case-insensitive isalnum -inline bool is_alnum(char c) { return is_alpha(c) || is_digit(c); } - -// @end-locale-independent functions for ASCII character set - -#ifdef FLATBUFFERS_PREFER_PRINTF -template size_t IntToDigitCount(T t) { - size_t digit_count = 0; - // Count the sign for negative numbers - if (t < 0) digit_count++; - // Count a single 0 left of the dot for fractional numbers - if (-1 < t && t < 1) digit_count++; - // Count digits until fractional part - T eps = std::numeric_limits::epsilon(); - while (t <= (-1 + eps) || (1 - eps) <= t) { - t /= 10; - digit_count++; - } - return digit_count; -} - -template size_t NumToStringWidth(T t, int precision = 0) { - size_t string_width = IntToDigitCount(t); - // Count the dot for floating point numbers - if (precision) string_width += (precision + 1); - return string_width; -} - -template -std::string NumToStringImplWrapper(T t, const char *fmt, int precision = 0) { - size_t string_width = NumToStringWidth(t, precision); - std::string s(string_width, 0x00); - // Allow snprintf to use std::string trailing null to detect buffer overflow - snprintf(const_cast(s.data()), (s.size() + 1), fmt, string_width, t); - return s; -} -#endif // FLATBUFFERS_PREFER_PRINTF - -// Convert an integer or floating point value to a string. -// In contrast to std::stringstream, "char" values are -// converted to a string of digits, and we don't use scientific notation. -template std::string NumToString(T t) { - // clang-format off - - #ifndef FLATBUFFERS_PREFER_PRINTF - std::stringstream ss; - ss << t; - return ss.str(); - #else // FLATBUFFERS_PREFER_PRINTF - auto v = static_cast(t); - return NumToStringImplWrapper(v, "%.*lld"); - #endif // FLATBUFFERS_PREFER_PRINTF - // clang-format on -} -// Avoid char types used as character data. -template<> inline std::string NumToString(signed char t) { - return NumToString(static_cast(t)); -} -template<> inline std::string NumToString(unsigned char t) { - return NumToString(static_cast(t)); -} -template<> inline std::string NumToString(char t) { - return NumToString(static_cast(t)); -} -#if defined(FLATBUFFERS_CPP98_STL) -template<> inline std::string NumToString(long long t) { - char buf[21]; // (log((1 << 63) - 1) / log(10)) + 2 - snprintf(buf, sizeof(buf), "%lld", t); - return std::string(buf); -} - -template<> -inline std::string NumToString(unsigned long long t) { - char buf[22]; // (log((1 << 63) - 1) / log(10)) + 1 - snprintf(buf, sizeof(buf), "%llu", t); - return std::string(buf); -} -#endif // defined(FLATBUFFERS_CPP98_STL) - -// Special versions for floats/doubles. -template std::string FloatToString(T t, int precision) { - // clang-format off - - #ifndef FLATBUFFERS_PREFER_PRINTF - // to_string() prints different numbers of digits for floats depending on - // platform and isn't available on Android, so we use stringstream - std::stringstream ss; - // Use std::fixed to suppress scientific notation. - ss << std::fixed; - // Default precision is 6, we want that to be higher for doubles. - ss << std::setprecision(precision); - ss << t; - auto s = ss.str(); - #else // FLATBUFFERS_PREFER_PRINTF - auto v = static_cast(t); - auto s = NumToStringImplWrapper(v, "%0.*f", precision); - #endif // FLATBUFFERS_PREFER_PRINTF - // clang-format on - // Sadly, std::fixed turns "1" into "1.00000", so here we undo that. - auto p = s.find_last_not_of('0'); - if (p != std::string::npos) { - // Strip trailing zeroes. If it is a whole number, keep one zero. - s.resize(p + (s[p] == '.' ? 2 : 1)); - } - return s; -} - -template<> inline std::string NumToString(double t) { - return FloatToString(t, 12); -} -template<> inline std::string NumToString(float t) { - return FloatToString(t, 6); -} - -// Convert an integer value to a hexadecimal string. -// The returned string length is always xdigits long, prefixed by 0 digits. -// For example, IntToStringHex(0x23, 8) returns the string "00000023". -inline std::string IntToStringHex(int i, int xdigits) { - FLATBUFFERS_ASSERT(i >= 0); - // clang-format off - - #ifndef FLATBUFFERS_PREFER_PRINTF - std::stringstream ss; - ss << std::setw(xdigits) << std::setfill('0') << std::hex << std::uppercase - << i; - return ss.str(); - #else // FLATBUFFERS_PREFER_PRINTF - return NumToStringImplWrapper(i, "%.*X", xdigits); - #endif // FLATBUFFERS_PREFER_PRINTF - // clang-format on -} - -// clang-format off -// Use locale independent functions {strtod_l, strtof_l, strtoll_l, strtoull_l}. -#if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && (FLATBUFFERS_LOCALE_INDEPENDENT > 0) - class ClassicLocale { - #ifdef _MSC_VER - typedef _locale_t locale_type; - #else - typedef locale_t locale_type; // POSIX.1-2008 locale_t type - #endif - ClassicLocale(); - ~ClassicLocale(); - locale_type locale_; - static ClassicLocale instance_; - public: - static locale_type Get() { return instance_.locale_; } - }; - - #ifdef _MSC_VER - #define __strtoull_impl(s, pe, b) _strtoui64_l(s, pe, b, ClassicLocale::Get()) - #define __strtoll_impl(s, pe, b) _strtoi64_l(s, pe, b, ClassicLocale::Get()) - #define __strtod_impl(s, pe) _strtod_l(s, pe, ClassicLocale::Get()) - #define __strtof_impl(s, pe) _strtof_l(s, pe, ClassicLocale::Get()) - #else - #define __strtoull_impl(s, pe, b) strtoull_l(s, pe, b, ClassicLocale::Get()) - #define __strtoll_impl(s, pe, b) strtoll_l(s, pe, b, ClassicLocale::Get()) - #define __strtod_impl(s, pe) strtod_l(s, pe, ClassicLocale::Get()) - #define __strtof_impl(s, pe) strtof_l(s, pe, ClassicLocale::Get()) - #endif -#else - #define __strtod_impl(s, pe) strtod(s, pe) - #define __strtof_impl(s, pe) static_cast(strtod(s, pe)) - #ifdef _MSC_VER - #define __strtoull_impl(s, pe, b) _strtoui64(s, pe, b) - #define __strtoll_impl(s, pe, b) _strtoi64(s, pe, b) - #else - #define __strtoull_impl(s, pe, b) strtoull(s, pe, b) - #define __strtoll_impl(s, pe, b) strtoll(s, pe, b) - #endif -#endif - -inline void strtoval_impl(int64_t *val, const char *str, char **endptr, - int base) { - *val = __strtoll_impl(str, endptr, base); -} - -inline void strtoval_impl(uint64_t *val, const char *str, char **endptr, - int base) { - *val = __strtoull_impl(str, endptr, base); -} - -inline void strtoval_impl(double *val, const char *str, char **endptr) { - *val = __strtod_impl(str, endptr); -} - -// UBSAN: double to float is safe if numeric_limits::is_iec559 is true. -__supress_ubsan__("float-cast-overflow") -inline void strtoval_impl(float *val, const char *str, char **endptr) { - *val = __strtof_impl(str, endptr); -} -#undef __strtoull_impl -#undef __strtoll_impl -#undef __strtod_impl -#undef __strtof_impl -// clang-format on - -// Adaptor for strtoull()/strtoll(). -// Flatbuffers accepts numbers with any count of leading zeros (-009 is -9), -// while strtoll with base=0 interprets first leading zero as octal prefix. -// In future, it is possible to add prefixed 0b0101. -// 1) Checks errno code for overflow condition (out of range). -// 2) If base <= 0, function try to detect base of number by prefix. -// -// Return value (like strtoull and strtoll, but reject partial result): -// - If successful, an integer value corresponding to the str is returned. -// - If full string conversion can't be performed, 0 is returned. -// - If the converted value falls out of range of corresponding return type, a -// range error occurs. In this case value MAX(T)/MIN(T) is returned. -template -inline bool StringToIntegerImpl(T *val, const char *const str, - const int base = 0, - const bool check_errno = true) { - // T is int64_t or uint64_T - FLATBUFFERS_ASSERT(str); - if (base <= 0) { - auto s = str; - while (*s && !is_digit(*s)) s++; - if (s[0] == '0' && is_alpha_char(s[1], 'X')) - return StringToIntegerImpl(val, str, 16, check_errno); - // if a prefix not match, try base=10 - return StringToIntegerImpl(val, str, 10, check_errno); - } else { - if (check_errno) errno = 0; // clear thread-local errno - auto endptr = str; - strtoval_impl(val, str, const_cast(&endptr), base); - if ((*endptr != '\0') || (endptr == str)) { - *val = 0; // erase partial result - return false; // invalid string - } - // errno is out-of-range, return MAX/MIN - if (check_errno && errno) return false; - return true; - } -} - -template -inline bool StringToFloatImpl(T *val, const char *const str) { - // Type T must be either float or double. - FLATBUFFERS_ASSERT(str && val); - auto end = str; - strtoval_impl(val, str, const_cast(&end)); - auto done = (end != str) && (*end == '\0'); - if (!done) *val = 0; // erase partial result - return done; -} - -// Convert a string to an instance of T. -// Return value (matched with StringToInteger64Impl and strtod): -// - If successful, a numeric value corresponding to the str is returned. -// - If full string conversion can't be performed, 0 is returned. -// - If the converted value falls out of range of corresponding return type, a -// range error occurs. In this case value MAX(T)/MIN(T) is returned. -template inline bool StringToNumber(const char *s, T *val) { - FLATBUFFERS_ASSERT(s && val); - int64_t i64; - // The errno check isn't needed, will return MAX/MIN on overflow. - if (StringToIntegerImpl(&i64, s, 0, false)) { - const int64_t max = (flatbuffers::numeric_limits::max)(); - const int64_t min = flatbuffers::numeric_limits::lowest(); - if (i64 > max) { - *val = static_cast(max); - return false; - } - if (i64 < min) { - // For unsigned types return max to distinguish from - // "no conversion can be performed" when 0 is returned. - *val = static_cast(flatbuffers::is_unsigned::value ? max : min); - return false; - } - *val = static_cast(i64); - return true; - } - *val = 0; - return false; -} - -template<> inline bool StringToNumber(const char *str, int64_t *val) { - return StringToIntegerImpl(val, str); -} - -template<> -inline bool StringToNumber(const char *str, uint64_t *val) { - if (!StringToIntegerImpl(val, str)) return false; - // The strtoull accepts negative numbers: - // If the minus sign was part of the input sequence, the numeric value - // calculated from the sequence of digits is negated as if by unary minus - // in the result type, which applies unsigned integer wraparound rules. - // Fix this behaviour (except -0). - if (*val) { - auto s = str; - while (*s && !is_digit(*s)) s++; - s = (s > str) ? (s - 1) : s; // step back to one symbol - if (*s == '-') { - // For unsigned types return the max to distinguish from - // "no conversion can be performed". - *val = (flatbuffers::numeric_limits::max)(); - return false; - } - } - return true; -} - -template<> inline bool StringToNumber(const char *s, float *val) { - return StringToFloatImpl(val, s); -} - -template<> inline bool StringToNumber(const char *s, double *val) { - return StringToFloatImpl(val, s); -} - -inline int64_t StringToInt(const char *s, int base = 10) { - int64_t val; - return StringToIntegerImpl(&val, s, base) ? val : 0; -} - -inline uint64_t StringToUInt(const char *s, int base = 10) { - uint64_t val; - return StringToIntegerImpl(&val, s, base) ? val : 0; -} - -typedef bool (*LoadFileFunction)(const char *filename, bool binary, - std::string *dest); -typedef bool (*FileExistsFunction)(const char *filename); - -LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function); - -FileExistsFunction SetFileExistsFunction( - FileExistsFunction file_exists_function); - -// Check if file "name" exists. -bool FileExists(const char *name); - -// Check if "name" exists and it is also a directory. -bool DirExists(const char *name); - -// Load file "name" into "buf" returning true if successful -// false otherwise. If "binary" is false data is read -// using ifstream's text mode, otherwise data is read with -// no transcoding. -bool LoadFile(const char *name, bool binary, std::string *buf); - -// Save data "buf" of length "len" bytes into a file -// "name" returning true if successful, false otherwise. -// If "binary" is false data is written using ifstream's -// text mode, otherwise data is written with no -// transcoding. -bool SaveFile(const char *name, const char *buf, size_t len, bool binary); - -// Save data "buf" into file "name" returning true if -// successful, false otherwise. If "binary" is false -// data is written using ifstream's text mode, otherwise -// data is written with no transcoding. -inline bool SaveFile(const char *name, const std::string &buf, bool binary) { - return SaveFile(name, buf.c_str(), buf.size(), binary); -} - -// Functionality for minimalistic portable path handling. - -// The functions below behave correctly regardless of whether posix ('/') or -// Windows ('/' or '\\') separators are used. - -// Any new separators inserted are always posix. -FLATBUFFERS_CONSTEXPR char kPathSeparator = '/'; - -// Returns the path with the extension, if any, removed. -std::string StripExtension(const std::string &filepath); - -// Returns the extension, if any. -std::string GetExtension(const std::string &filepath); - -// Return the last component of the path, after the last separator. -std::string StripPath(const std::string &filepath); - -// Strip the last component of the path + separator. -std::string StripFileName(const std::string &filepath); - -// Concatenates a path with a filename, regardless of whether the path -// ends in a separator or not. -std::string ConCatPathFileName(const std::string &path, - const std::string &filename); - -// Replaces any '\\' separators with '/' -std::string PosixPath(const char *path); - -// This function ensure a directory exists, by recursively -// creating dirs for any parts of the path that don't exist yet. -void EnsureDirExists(const std::string &filepath); - -// Obtains the absolute path from any other path. -// Returns the input path if the absolute path couldn't be resolved. -std::string AbsolutePath(const std::string &filepath); - -// To and from UTF-8 unicode conversion functions - -// Convert a unicode code point into a UTF-8 representation by appending it -// to a string. Returns the number of bytes generated. -inline int ToUTF8(uint32_t ucc, std::string *out) { - FLATBUFFERS_ASSERT(!(ucc & 0x80000000)); // Top bit can't be set. - // 6 possible encodings: http://en.wikipedia.org/wiki/UTF-8 - for (int i = 0; i < 6; i++) { - // Max bits this encoding can represent. - uint32_t max_bits = 6 + i * 5 + static_cast(!i); - if (ucc < (1u << max_bits)) { // does it fit? - // Remaining bits not encoded in the first byte, store 6 bits each - uint32_t remain_bits = i * 6; - // Store first byte: - (*out) += static_cast((0xFE << (max_bits - remain_bits)) | - (ucc >> remain_bits)); - // Store remaining bytes: - for (int j = i - 1; j >= 0; j--) { - (*out) += static_cast(((ucc >> (j * 6)) & 0x3F) | 0x80); - } - return i + 1; // Return the number of bytes added. - } - } - FLATBUFFERS_ASSERT(0); // Impossible to arrive here. - return -1; -} - -// Converts whatever prefix of the incoming string corresponds to a valid -// UTF-8 sequence into a unicode code. The incoming pointer will have been -// advanced past all bytes parsed. -// returns -1 upon corrupt UTF-8 encoding (ignore the incoming pointer in -// this case). -inline int FromUTF8(const char **in) { - int len = 0; - // Count leading 1 bits. - for (int mask = 0x80; mask >= 0x04; mask >>= 1) { - if (**in & mask) { - len++; - } else { - break; - } - } - if ((static_cast(**in) << len) & 0x80) - return -1; // Bit after leading 1's must be 0. - if (!len) return *(*in)++; - // UTF-8 encoded values with a length are between 2 and 4 bytes. - if (len < 2 || len > 4) { return -1; } - // Grab initial bits of the code. - int ucc = *(*in)++ & ((1 << (7 - len)) - 1); - for (int i = 0; i < len - 1; i++) { - if ((**in & 0xC0) != 0x80) return -1; // Upper bits must 1 0. - ucc <<= 6; - ucc |= *(*in)++ & 0x3F; // Grab 6 more bits of the code. - } - // UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for - // UTF-16 surrogate pairs). - if (ucc >= 0xD800 && ucc <= 0xDFFF) { return -1; } - // UTF-8 must represent code points in their shortest possible encoding. - switch (len) { - case 2: - // Two bytes of UTF-8 can represent code points from U+0080 to U+07FF. - if (ucc < 0x0080 || ucc > 0x07FF) { return -1; } - break; - case 3: - // Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF. - if (ucc < 0x0800 || ucc > 0xFFFF) { return -1; } - break; - case 4: - // Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF. - if (ucc < 0x10000 || ucc > 0x10FFFF) { return -1; } - break; - } - return ucc; -} - -#ifndef FLATBUFFERS_PREFER_PRINTF -// Wraps a string to a maximum length, inserting new lines where necessary. Any -// existing whitespace will be collapsed down to a single space. A prefix or -// suffix can be provided, which will be inserted before or after a wrapped -// line, respectively. -inline std::string WordWrap(const std::string in, size_t max_length, - const std::string wrapped_line_prefix, - const std::string wrapped_line_suffix) { - std::istringstream in_stream(in); - std::string wrapped, line, word; - - in_stream >> word; - line = word; - - while (in_stream >> word) { - if ((line.length() + 1 + word.length() + wrapped_line_suffix.length()) < - max_length) { - line += " " + word; - } else { - wrapped += line + wrapped_line_suffix + "\n"; - line = wrapped_line_prefix + word; - } - } - wrapped += line; - - return wrapped; -} -#endif // !FLATBUFFERS_PREFER_PRINTF - -inline bool EscapeString(const char *s, size_t length, std::string *_text, - bool allow_non_utf8, bool natural_utf8) { - std::string &text = *_text; - text += "\""; - for (uoffset_t i = 0; i < length; i++) { - char c = s[i]; - switch (c) { - case '\n': text += "\\n"; break; - case '\t': text += "\\t"; break; - case '\r': text += "\\r"; break; - case '\b': text += "\\b"; break; - case '\f': text += "\\f"; break; - case '\"': text += "\\\""; break; - case '\\': text += "\\\\"; break; - default: - if (c >= ' ' && c <= '~') { - text += c; - } else { - // Not printable ASCII data. Let's see if it's valid UTF-8 first: - const char *utf8 = s + i; - int ucc = FromUTF8(&utf8); - if (ucc < 0) { - if (allow_non_utf8) { - text += "\\x"; - text += IntToStringHex(static_cast(c), 2); - } else { - // There are two cases here: - // - // 1) We reached here by parsing an IDL file. In that case, - // we previously checked for non-UTF-8, so we shouldn't reach - // here. - // - // 2) We reached here by someone calling GenerateText() - // on a previously-serialized flatbuffer. The data might have - // non-UTF-8 Strings, or might be corrupt. - // - // In both cases, we have to give up and inform the caller - // they have no JSON. - return false; - } - } else { - if (natural_utf8) { - // utf8 points to past all utf-8 bytes parsed - text.append(s + i, static_cast(utf8 - s - i)); - } else if (ucc <= 0xFFFF) { - // Parses as Unicode within JSON's \uXXXX range, so use that. - text += "\\u"; - text += IntToStringHex(ucc, 4); - } else if (ucc <= 0x10FFFF) { - // Encode Unicode SMP values to a surrogate pair using two \u - // escapes. - uint32_t base = ucc - 0x10000; - auto high_surrogate = (base >> 10) + 0xD800; - auto low_surrogate = (base & 0x03FF) + 0xDC00; - text += "\\u"; - text += IntToStringHex(high_surrogate, 4); - text += "\\u"; - text += IntToStringHex(low_surrogate, 4); - } - // Skip past characters recognized. - i = static_cast(utf8 - s - 1); - } - } - break; - } - } - text += "\""; - return true; -} - -inline std::string BufferToHexText(const void *buffer, size_t buffer_size, - size_t max_length, - const std::string &wrapped_line_prefix, - const std::string &wrapped_line_suffix) { - std::string text = wrapped_line_prefix; - size_t start_offset = 0; - const char *s = reinterpret_cast(buffer); - for (size_t i = 0; s && i < buffer_size; i++) { - // Last iteration or do we have more? - bool have_more = i + 1 < buffer_size; - text += "0x"; - text += IntToStringHex(static_cast(s[i]), 2); - if (have_more) { text += ','; } - // If we have more to process and we reached max_length - if (have_more && - text.size() + wrapped_line_suffix.size() >= start_offset + max_length) { - text += wrapped_line_suffix; - text += '\n'; - start_offset = text.size(); - text += wrapped_line_prefix; - } - } - text += wrapped_line_suffix; - return text; -} - -// Remove paired quotes in a string: "text"|'text' -> text. -std::string RemoveStringQuotes(const std::string &s); - -// Change th global C-locale to locale with name . -// Returns an actual locale name in <_value>, useful if locale_name is "" or -// null. -bool SetGlobalTestLocale(const char *locale_name, - std::string *_value = nullptr); - -// Read (or test) a value of environment variable. -bool ReadEnvironmentVariable(const char *var_name, - std::string *_value = nullptr); - -// MSVC specific: Send all assert reports to STDOUT to prevent CI hangs. -void SetupDefaultCRTReportMode(); - -} // namespace flatbuffers - -#endif // FLATBUFFERS_UTIL_H_ diff --git a/daemon/src/External/src/flatbuffers/idl_parser.cpp b/daemon/src/External/src/flatbuffers/idl_parser.cpp deleted file mode 100644 index 6faca7ac..00000000 --- a/daemon/src/External/src/flatbuffers/idl_parser.cpp +++ /dev/null @@ -1,3655 +0,0 @@ -/* - * Copyright 2014 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#include "flatbuffers/idl.h" -#include "flatbuffers/util.h" - -namespace flatbuffers { - -// Reflects the version at the compiling time of binary(lib/dll/so). -const char *FLATBUFFERS_VERSION() { - // clang-format off - return - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "." - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "." - FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION); - // clang-format on -} - -const double kPi = 3.14159265358979323846; - -// clang-format off -const char *const kTypeNames[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \ - IDLTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - nullptr -}; - -const char kTypeSizes[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - sizeof(CTYPE), - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD -}; -// clang-format on - -// The enums in the reflection schema should match the ones we use internally. -// Compare the last element to check if these go out of sync. -static_assert(BASE_TYPE_UNION == static_cast(reflection::Union), - "enums don't match"); - -// Any parsing calls have to be wrapped in this macro, which automates -// handling of recursive error checking a bit. It will check the received -// CheckedError object, and return straight away on error. -#define ECHECK(call) \ - { \ - auto ce = (call); \ - if (ce.Check()) return ce; \ - } - -// These two functions are called hundreds of times below, so define a short -// form: -#define NEXT() ECHECK(Next()) -#define EXPECT(tok) ECHECK(Expect(tok)) - -static bool ValidateUTF8(const std::string &str) { - const char *s = &str[0]; - const char *const sEnd = s + str.length(); - while (s < sEnd) { - if (FromUTF8(&s) < 0) { return false; } - } - return true; -} - -static bool IsLowerSnakeCase(const std::string &str) { - for (size_t i = 0; i < str.length(); i++) { - char c = str[i]; - if (!check_ascii_range(c, 'a', 'z') && !is_digit(c) && c != '_') { - return false; - } - } - return true; -} - -// Convert an underscore_based_indentifier in to camelCase. -// Also uppercases the first character if first is true. -std::string MakeCamel(const std::string &in, bool first) { - std::string s; - for (size_t i = 0; i < in.length(); i++) { - if (!i && first) - s += static_cast(toupper(in[0])); - else if (in[i] == '_' && i + 1 < in.length()) - s += static_cast(toupper(in[++i])); - else - s += in[i]; - } - return s; -} - -// Convert an underscore_based_identifier in to screaming snake case. -std::string MakeScreamingCamel(const std::string &in) { - std::string s; - for (size_t i = 0; i < in.length(); i++) { - if (in[i] != '_') - s += static_cast(toupper(in[i])); - else - s += in[i]; - } - return s; -} - -void DeserializeDoc(std::vector &doc, - const Vector> *documentation) { - if (documentation == nullptr) return; - for (uoffset_t index = 0; index < documentation->size(); index++) - doc.push_back(documentation->Get(index)->str()); -} - -void Parser::Message(const std::string &msg) { - if (!error_.empty()) error_ += "\n"; // log all warnings and errors - error_ += file_being_parsed_.length() ? AbsolutePath(file_being_parsed_) : ""; - // clang-format off - - #ifdef _WIN32 // MSVC alike - error_ += - "(" + NumToString(line_) + ", " + NumToString(CursorPosition()) + ")"; - #else // gcc alike - if (file_being_parsed_.length()) error_ += ":"; - error_ += NumToString(line_) + ": " + NumToString(CursorPosition()); - #endif - // clang-format on - error_ += ": " + msg; -} - -void Parser::Warning(const std::string &msg) { Message("warning: " + msg); } - -CheckedError Parser::Error(const std::string &msg) { - Message("error: " + msg); - return CheckedError(true); -} - -inline CheckedError NoError() { return CheckedError(false); } - -CheckedError Parser::RecurseError() { - return Error("maximum parsing recursion of " + - NumToString(FLATBUFFERS_MAX_PARSING_DEPTH) + " reached"); -} - -template CheckedError Parser::Recurse(F f) { - if (recurse_protection_counter >= (FLATBUFFERS_MAX_PARSING_DEPTH)) - return RecurseError(); - recurse_protection_counter++; - auto ce = f(); - recurse_protection_counter--; - return ce; -} - -template std::string TypeToIntervalString() { - return "[" + NumToString((flatbuffers::numeric_limits::lowest)()) + "; " + - NumToString((flatbuffers::numeric_limits::max)()) + "]"; -} - -// atot: template version of atoi/atof: convert a string to an instance of T. -template -inline CheckedError atot(const char *s, Parser &parser, T *val) { - auto done = StringToNumber(s, val); - if (done) return NoError(); - if (0 == *val) - return parser.Error("invalid number: \"" + std::string(s) + "\""); - else - return parser.Error("invalid number: \"" + std::string(s) + "\"" + - ", constant does not fit " + TypeToIntervalString()); -} -template<> -inline CheckedError atot>(const char *s, Parser &parser, - Offset *val) { - (void)parser; - *val = Offset(atoi(s)); - return NoError(); -} - -std::string Namespace::GetFullyQualifiedName(const std::string &name, - size_t max_components) const { - // Early exit if we don't have a defined namespace. - if (components.empty() || !max_components) { return name; } - std::string stream_str; - for (size_t i = 0; i < std::min(components.size(), max_components); i++) { - if (i) { stream_str += '.'; } - stream_str += std::string(components[i]); - } - if (name.length()) { - stream_str += '.'; - stream_str += name; - } - return stream_str; -} - -// Declare tokens we'll use. Single character tokens are represented by their -// ascii character code (e.g. '{'), others above 256. -// clang-format off -#define FLATBUFFERS_GEN_TOKENS(TD) \ - TD(Eof, 256, "end of file") \ - TD(StringConstant, 257, "string constant") \ - TD(IntegerConstant, 258, "integer constant") \ - TD(FloatConstant, 259, "float constant") \ - TD(Identifier, 260, "identifier") -#ifdef __GNUC__ -__extension__ // Stop GCC complaining about trailing comma with -Wpendantic. -#endif -enum { - #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) kToken ## NAME = VALUE, - FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN) - #undef FLATBUFFERS_TOKEN -}; - -static std::string TokenToString(int t) { - static const char * const tokens[] = { - #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) STRING, - FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN) - #undef FLATBUFFERS_TOKEN - #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \ - IDLTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - if (t < 256) { // A single ascii char token. - std::string s; - s.append(1, static_cast(t)); - return s; - } else { // Other tokens. - return tokens[t - 256]; - } -} -// clang-format on - -std::string Parser::TokenToStringId(int t) const { - return t == kTokenIdentifier ? attribute_ : TokenToString(t); -} - -// Parses exactly nibbles worth of hex digits into a number, or error. -CheckedError Parser::ParseHexNum(int nibbles, uint64_t *val) { - FLATBUFFERS_ASSERT(nibbles > 0); - for (int i = 0; i < nibbles; i++) - if (!is_xdigit(cursor_[i])) - return Error("escape code must be followed by " + NumToString(nibbles) + - " hex digits"); - std::string target(cursor_, cursor_ + nibbles); - *val = StringToUInt(target.c_str(), 16); - cursor_ += nibbles; - return NoError(); -} - -CheckedError Parser::SkipByteOrderMark() { - if (static_cast(*cursor_) != 0xef) return NoError(); - cursor_++; - if (static_cast(*cursor_) != 0xbb) - return Error("invalid utf-8 byte order mark"); - cursor_++; - if (static_cast(*cursor_) != 0xbf) - return Error("invalid utf-8 byte order mark"); - cursor_++; - return NoError(); -} - -static inline bool IsIdentifierStart(char c) { - return is_alpha(c) || (c == '_'); -} - -CheckedError Parser::Next() { - doc_comment_.clear(); - bool seen_newline = cursor_ == source_; - attribute_.clear(); - attr_is_trivial_ascii_string_ = true; - for (;;) { - char c = *cursor_++; - token_ = c; - switch (c) { - case '\0': - cursor_--; - token_ = kTokenEof; - return NoError(); - case ' ': - case '\r': - case '\t': break; - case '\n': - MarkNewLine(); - seen_newline = true; - break; - case '{': - case '}': - case '(': - case ')': - case '[': - case ']': - case ',': - case ':': - case ';': - case '=': return NoError(); - case '\"': - case '\'': { - int unicode_high_surrogate = -1; - - while (*cursor_ != c) { - if (*cursor_ < ' ' && static_cast(*cursor_) >= 0) - return Error("illegal character in string constant"); - if (*cursor_ == '\\') { - attr_is_trivial_ascii_string_ = false; // has escape sequence - cursor_++; - if (unicode_high_surrogate != -1 && *cursor_ != 'u') { - return Error( - "illegal Unicode sequence (unpaired high surrogate)"); - } - switch (*cursor_) { - case 'n': - attribute_ += '\n'; - cursor_++; - break; - case 't': - attribute_ += '\t'; - cursor_++; - break; - case 'r': - attribute_ += '\r'; - cursor_++; - break; - case 'b': - attribute_ += '\b'; - cursor_++; - break; - case 'f': - attribute_ += '\f'; - cursor_++; - break; - case '\"': - attribute_ += '\"'; - cursor_++; - break; - case '\'': - attribute_ += '\''; - cursor_++; - break; - case '\\': - attribute_ += '\\'; - cursor_++; - break; - case '/': - attribute_ += '/'; - cursor_++; - break; - case 'x': { // Not in the JSON standard - cursor_++; - uint64_t val; - ECHECK(ParseHexNum(2, &val)); - attribute_ += static_cast(val); - break; - } - case 'u': { - cursor_++; - uint64_t val; - ECHECK(ParseHexNum(4, &val)); - if (val >= 0xD800 && val <= 0xDBFF) { - if (unicode_high_surrogate != -1) { - return Error( - "illegal Unicode sequence (multiple high surrogates)"); - } else { - unicode_high_surrogate = static_cast(val); - } - } else if (val >= 0xDC00 && val <= 0xDFFF) { - if (unicode_high_surrogate == -1) { - return Error( - "illegal Unicode sequence (unpaired low surrogate)"); - } else { - int code_point = 0x10000 + - ((unicode_high_surrogate & 0x03FF) << 10) + - (val & 0x03FF); - ToUTF8(code_point, &attribute_); - unicode_high_surrogate = -1; - } - } else { - if (unicode_high_surrogate != -1) { - return Error( - "illegal Unicode sequence (unpaired high surrogate)"); - } - ToUTF8(static_cast(val), &attribute_); - } - break; - } - default: return Error("unknown escape code in string constant"); - } - } else { // printable chars + UTF-8 bytes - if (unicode_high_surrogate != -1) { - return Error( - "illegal Unicode sequence (unpaired high surrogate)"); - } - // reset if non-printable - attr_is_trivial_ascii_string_ &= - check_ascii_range(*cursor_, ' ', '~'); - - attribute_ += *cursor_++; - } - } - if (unicode_high_surrogate != -1) { - return Error("illegal Unicode sequence (unpaired high surrogate)"); - } - cursor_++; - if (!attr_is_trivial_ascii_string_ && !opts.allow_non_utf8 && - !ValidateUTF8(attribute_)) { - return Error("illegal UTF-8 sequence"); - } - token_ = kTokenStringConstant; - return NoError(); - } - case '/': - if (*cursor_ == '/') { - const char *start = ++cursor_; - while (*cursor_ && *cursor_ != '\n' && *cursor_ != '\r') cursor_++; - if (*start == '/') { // documentation comment - if (!seen_newline) - return Error( - "a documentation comment should be on a line on its own"); - doc_comment_.push_back(std::string(start + 1, cursor_)); - } - break; - } else if (*cursor_ == '*') { - cursor_++; - // TODO: make nested. - while (*cursor_ != '*' || cursor_[1] != '/') { - if (*cursor_ == '\n') MarkNewLine(); - if (!*cursor_) return Error("end of file in comment"); - cursor_++; - } - cursor_ += 2; - break; - } - FLATBUFFERS_FALLTHROUGH(); // else fall thru - default: - const auto has_sign = (c == '+') || (c == '-'); - // '-'/'+' and following identifier - can be a predefined constant like: - // NAN, INF, PI, etc or it can be a function name like cos/sin/deg. - if (IsIdentifierStart(c) || (has_sign && IsIdentifierStart(*cursor_))) { - // Collect all chars of an identifier: - const char *start = cursor_ - 1; - while (IsIdentifierStart(*cursor_) || is_digit(*cursor_)) cursor_++; - attribute_.append(start, cursor_); - token_ = has_sign ? kTokenStringConstant : kTokenIdentifier; - return NoError(); - } - - auto dot_lvl = - (c == '.') ? 0 : 1; // dot_lvl==0 <=> exactly one '.' seen - if (!dot_lvl && !is_digit(*cursor_)) return NoError(); // enum? - // Parser accepts hexadecimal-floating-literal (see C++ 5.13.4). - if (is_digit(c) || has_sign || !dot_lvl) { - const auto start = cursor_ - 1; - auto start_digits = !is_digit(c) ? cursor_ : cursor_ - 1; - if (!is_digit(c) && is_digit(*cursor_)) { - start_digits = cursor_; // see digit in cursor_ position - c = *cursor_++; - } - // hex-float can't begind with '.' - auto use_hex = dot_lvl && (c == '0') && is_alpha_char(*cursor_, 'X'); - if (use_hex) start_digits = ++cursor_; // '0x' is the prefix, skip it - // Read an integer number or mantisa of float-point number. - do { - if (use_hex) { - while (is_xdigit(*cursor_)) cursor_++; - } else { - while (is_digit(*cursor_)) cursor_++; - } - } while ((*cursor_ == '.') && (++cursor_) && (--dot_lvl >= 0)); - // Exponent of float-point number. - if ((dot_lvl >= 0) && (cursor_ > start_digits)) { - // The exponent suffix of hexadecimal float number is mandatory. - if (use_hex && !dot_lvl) start_digits = cursor_; - if ((use_hex && is_alpha_char(*cursor_, 'P')) || - is_alpha_char(*cursor_, 'E')) { - dot_lvl = 0; // Emulate dot to signal about float-point number. - cursor_++; - if (*cursor_ == '+' || *cursor_ == '-') cursor_++; - start_digits = cursor_; // the exponent-part has to have digits - // Exponent is decimal integer number - while (is_digit(*cursor_)) cursor_++; - if (*cursor_ == '.') { - cursor_++; // If see a dot treat it as part of invalid number. - dot_lvl = -1; // Fall thru to Error(). - } - } - } - // Finalize. - if ((dot_lvl >= 0) && (cursor_ > start_digits)) { - attribute_.append(start, cursor_); - token_ = dot_lvl ? kTokenIntegerConstant : kTokenFloatConstant; - return NoError(); - } else { - return Error("invalid number: " + std::string(start, cursor_)); - } - } - std::string ch; - ch = c; - if (false == check_ascii_range(c, ' ', '~')) - ch = "code: " + NumToString(c); - return Error("illegal character: " + ch); - } - } -} - -// Check if a given token is next. -bool Parser::Is(int t) const { return t == token_; } - -bool Parser::IsIdent(const char *id) const { - return token_ == kTokenIdentifier && attribute_ == id; -} - -// Expect a given token to be next, consume it, or error if not present. -CheckedError Parser::Expect(int t) { - if (t != token_) { - return Error("expecting: " + TokenToString(t) + - " instead got: " + TokenToStringId(token_)); - } - NEXT(); - return NoError(); -} - -CheckedError Parser::ParseNamespacing(std::string *id, std::string *last) { - while (Is('.')) { - NEXT(); - *id += "."; - *id += attribute_; - if (last) *last = attribute_; - EXPECT(kTokenIdentifier); - } - return NoError(); -} - -EnumDef *Parser::LookupEnum(const std::string &id) { - // Search thru parent namespaces. - for (int components = static_cast(current_namespace_->components.size()); - components >= 0; components--) { - auto ed = enums_.Lookup( - current_namespace_->GetFullyQualifiedName(id, components)); - if (ed) return ed; - } - return nullptr; -} - -StructDef *Parser::LookupStruct(const std::string &id) const { - auto sd = structs_.Lookup(id); - if (sd) sd->refcount++; - return sd; -} - -CheckedError Parser::ParseTypeIdent(Type &type) { - std::string id = attribute_; - EXPECT(kTokenIdentifier); - ECHECK(ParseNamespacing(&id, nullptr)); - auto enum_def = LookupEnum(id); - if (enum_def) { - type = enum_def->underlying_type; - if (enum_def->is_union) type.base_type = BASE_TYPE_UNION; - } else { - type.base_type = BASE_TYPE_STRUCT; - type.struct_def = LookupCreateStruct(id); - } - return NoError(); -} - -// Parse any IDL type. -CheckedError Parser::ParseType(Type &type) { - if (token_ == kTokenIdentifier) { - if (IsIdent("bool")) { - type.base_type = BASE_TYPE_BOOL; - NEXT(); - } else if (IsIdent("byte") || IsIdent("int8")) { - type.base_type = BASE_TYPE_CHAR; - NEXT(); - } else if (IsIdent("ubyte") || IsIdent("uint8")) { - type.base_type = BASE_TYPE_UCHAR; - NEXT(); - } else if (IsIdent("short") || IsIdent("int16")) { - type.base_type = BASE_TYPE_SHORT; - NEXT(); - } else if (IsIdent("ushort") || IsIdent("uint16")) { - type.base_type = BASE_TYPE_USHORT; - NEXT(); - } else if (IsIdent("int") || IsIdent("int32")) { - type.base_type = BASE_TYPE_INT; - NEXT(); - } else if (IsIdent("uint") || IsIdent("uint32")) { - type.base_type = BASE_TYPE_UINT; - NEXT(); - } else if (IsIdent("long") || IsIdent("int64")) { - type.base_type = BASE_TYPE_LONG; - NEXT(); - } else if (IsIdent("ulong") || IsIdent("uint64")) { - type.base_type = BASE_TYPE_ULONG; - NEXT(); - } else if (IsIdent("float") || IsIdent("float32")) { - type.base_type = BASE_TYPE_FLOAT; - NEXT(); - } else if (IsIdent("double") || IsIdent("float64")) { - type.base_type = BASE_TYPE_DOUBLE; - NEXT(); - } else if (IsIdent("string")) { - type.base_type = BASE_TYPE_STRING; - NEXT(); - } else { - ECHECK(ParseTypeIdent(type)); - } - } else if (token_ == '[') { - NEXT(); - Type subtype; - ECHECK(Recurse([&]() { return ParseType(subtype); })); - if (IsSeries(subtype)) { - // We could support this, but it will complicate things, and it's - // easier to work around with a struct around the inner vector. - return Error("nested vector types not supported (wrap in table first)"); - } - if (token_ == ':') { - NEXT(); - if (token_ != kTokenIntegerConstant) { - return Error("length of fixed-length array must be an integer value"); - } - uint16_t fixed_length = 0; - bool check = StringToNumber(attribute_.c_str(), &fixed_length); - if (!check || fixed_length < 1) { - return Error( - "length of fixed-length array must be positive and fit to " - "uint16_t type"); - } - type = Type(BASE_TYPE_ARRAY, subtype.struct_def, subtype.enum_def, - fixed_length); - NEXT(); - } else { - type = Type(BASE_TYPE_VECTOR, subtype.struct_def, subtype.enum_def); - } - type.element = subtype.base_type; - EXPECT(']'); - } else { - return Error("illegal type syntax"); - } - return NoError(); -} - -CheckedError Parser::AddField(StructDef &struct_def, const std::string &name, - const Type &type, FieldDef **dest) { - auto &field = *new FieldDef(); - field.value.offset = - FieldIndexToOffset(static_cast(struct_def.fields.vec.size())); - field.name = name; - field.file = struct_def.file; - field.value.type = type; - if (struct_def.fixed) { // statically compute the field offset - auto size = InlineSize(type); - auto alignment = InlineAlignment(type); - // structs_ need to have a predictable format, so we need to align to - // the largest scalar - struct_def.minalign = std::max(struct_def.minalign, alignment); - struct_def.PadLastField(alignment); - field.value.offset = static_cast(struct_def.bytesize); - struct_def.bytesize += size; - } - if (struct_def.fields.Add(name, &field)) - return Error("field already exists: " + name); - *dest = &field; - return NoError(); -} - -CheckedError Parser::ParseField(StructDef &struct_def) { - std::string name = attribute_; - - if (LookupCreateStruct(name, false, false)) - return Error("field name can not be the same as table/struct name"); - - if (!IsLowerSnakeCase(name)) { - Warning("field names should be lowercase snake_case, got: " + name); - } - - std::vector dc = doc_comment_; - EXPECT(kTokenIdentifier); - EXPECT(':'); - Type type; - ECHECK(ParseType(type)); - - if (struct_def.fixed) { - auto valid = IsScalar(type.base_type) || IsStruct(type); - if (!valid && IsArray(type)) { - const auto &elem_type = type.VectorType(); - valid |= IsScalar(elem_type.base_type) || IsStruct(elem_type); - } - if (!valid) - return Error("structs may contain only scalar or struct fields"); - } - - if (!struct_def.fixed && IsArray(type)) - return Error("fixed-length array in table must be wrapped in struct"); - - if (IsArray(type) && !SupportsAdvancedArrayFeatures()) { - return Error( - "Arrays are not yet supported in all " - "the specified programming languages."); - } - - FieldDef *typefield = nullptr; - if (type.base_type == BASE_TYPE_UNION) { - // For union fields, add a second auto-generated field to hold the type, - // with a special suffix. - ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(), - type.enum_def->underlying_type, &typefield)); - } else if (type.base_type == BASE_TYPE_VECTOR && - type.element == BASE_TYPE_UNION) { - // Only cpp, js and ts supports the union vector feature so far. - if (!SupportsAdvancedUnionFeatures()) { - return Error( - "Vectors of unions are not yet supported in all " - "the specified programming languages."); - } - // For vector of union fields, add a second auto-generated vector field to - // hold the types, with a special suffix. - Type union_vector(BASE_TYPE_VECTOR, nullptr, type.enum_def); - union_vector.element = BASE_TYPE_UTYPE; - ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(), union_vector, - &typefield)); - } - - FieldDef *field; - ECHECK(AddField(struct_def, name, type, &field)); - - if (token_ == '=') { - NEXT(); - ECHECK(ParseSingleValue(&field->name, field->value, true)); - if (!IsScalar(type.base_type) || - (struct_def.fixed && field->value.constant != "0")) - return Error( - "default values currently only supported for scalars in tables"); - } - // Append .0 if the value has not it (skip hex and scientific floats). - // This suffix needed for generated C++ code. - if (IsFloat(type.base_type)) { - auto &text = field->value.constant; - FLATBUFFERS_ASSERT(false == text.empty()); - auto s = text.c_str(); - while (*s == ' ') s++; - if (*s == '-' || *s == '+') s++; - // 1) A float constants (nan, inf, pi, etc) is a kind of identifier. - // 2) A float number needn't ".0" at the end if it has exponent. - if ((false == IsIdentifierStart(*s)) && - (std::string::npos == field->value.constant.find_first_of(".eEpP"))) { - field->value.constant += ".0"; - } - } - if (type.enum_def) { - // The type.base_type can only be scalar, union, array or vector. - // Table, struct or string can't have enum_def. - // Default value of union and vector in NONE, NULL translated to "0". - FLATBUFFERS_ASSERT(IsInteger(type.base_type) || - (type.base_type == BASE_TYPE_UNION) || - (type.base_type == BASE_TYPE_VECTOR) || - (type.base_type == BASE_TYPE_ARRAY)); - if (type.base_type == BASE_TYPE_VECTOR) { - // Vector can't use initialization list. - FLATBUFFERS_ASSERT(field->value.constant == "0"); - } else { - // All unions should have the NONE ("0") enum value. - auto in_enum = type.enum_def->attributes.Lookup("bit_flags") || - type.enum_def->FindByValue(field->value.constant); - if (false == in_enum) - return Error("default value of " + field->value.constant + - " for field " + name + " is not part of enum " + - type.enum_def->name); - } - } - - field->doc_comment = dc; - ECHECK(ParseMetaData(&field->attributes)); - field->deprecated = field->attributes.Lookup("deprecated") != nullptr; - auto hash_name = field->attributes.Lookup("hash"); - if (hash_name) { - switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element - : type.base_type) { - case BASE_TYPE_SHORT: - case BASE_TYPE_USHORT: { - if (FindHashFunction16(hash_name->constant.c_str()) == nullptr) - return Error("Unknown hashing algorithm for 16 bit types: " + - hash_name->constant); - break; - } - case BASE_TYPE_INT: - case BASE_TYPE_UINT: { - if (FindHashFunction32(hash_name->constant.c_str()) == nullptr) - return Error("Unknown hashing algorithm for 32 bit types: " + - hash_name->constant); - break; - } - case BASE_TYPE_LONG: - case BASE_TYPE_ULONG: { - if (FindHashFunction64(hash_name->constant.c_str()) == nullptr) - return Error("Unknown hashing algorithm for 64 bit types: " + - hash_name->constant); - break; - } - default: - return Error( - "only short, ushort, int, uint, long and ulong data types support " - "hashing."); - } - } - auto cpp_type = field->attributes.Lookup("cpp_type"); - if (cpp_type) { - if (!hash_name) - return Error("cpp_type can only be used with a hashed field"); - /// forcing cpp_ptr_type to 'naked' if unset - auto cpp_ptr_type = field->attributes.Lookup("cpp_ptr_type"); - if (!cpp_ptr_type) { - auto val = new Value(); - val->type = cpp_type->type; - val->constant = "naked"; - field->attributes.Add("cpp_ptr_type", val); - } - } - if (field->deprecated && struct_def.fixed) - return Error("can't deprecate fields in a struct"); - field->required = field->attributes.Lookup("required") != nullptr; - if (field->required && (struct_def.fixed || IsScalar(type.base_type))) - return Error("only non-scalar fields in tables may be 'required'"); - field->key = field->attributes.Lookup("key") != nullptr; - if (field->key) { - if (struct_def.has_key) return Error("only one field may be set as 'key'"); - struct_def.has_key = true; - if (!IsScalar(type.base_type)) { - field->required = true; - if (type.base_type != BASE_TYPE_STRING) - return Error("'key' field must be string or scalar type"); - } - } - field->shared = field->attributes.Lookup("shared") != nullptr; - if (field->shared && field->value.type.base_type != BASE_TYPE_STRING) - return Error("shared can only be defined on strings"); - - auto field_native_custom_alloc = - field->attributes.Lookup("native_custom_alloc"); - if (field_native_custom_alloc) - return Error( - "native_custom_alloc can only be used with a table or struct " - "definition"); - - field->native_inline = field->attributes.Lookup("native_inline") != nullptr; - if (field->native_inline && !IsStruct(field->value.type)) - return Error("native_inline can only be defined on structs"); - - auto nested = field->attributes.Lookup("nested_flatbuffer"); - if (nested) { - if (nested->type.base_type != BASE_TYPE_STRING) - return Error( - "nested_flatbuffer attribute must be a string (the root type)"); - if (type.base_type != BASE_TYPE_VECTOR || type.element != BASE_TYPE_UCHAR) - return Error( - "nested_flatbuffer attribute may only apply to a vector of ubyte"); - // This will cause an error if the root type of the nested flatbuffer - // wasn't defined elsewhere. - field->nested_flatbuffer = LookupCreateStruct(nested->constant); - } - - if (field->attributes.Lookup("flexbuffer")) { - field->flexbuffer = true; - uses_flexbuffers_ = true; - if (type.base_type != BASE_TYPE_VECTOR || type.element != BASE_TYPE_UCHAR) - return Error("flexbuffer attribute may only apply to a vector of ubyte"); - } - - if (typefield) { - if (!IsScalar(typefield->value.type.base_type)) { - // this is a union vector field - typefield->required = field->required; - } - // If this field is a union, and it has a manually assigned id, - // the automatically added type field should have an id as well (of N - 1). - auto attr = field->attributes.Lookup("id"); - if (attr) { - auto id = atoi(attr->constant.c_str()); - auto val = new Value(); - val->type = attr->type; - val->constant = NumToString(id - 1); - typefield->attributes.Add("id", val); - } - // if this field is a union that is deprecated, - // the automatically added type field should be deprecated as well - if (field->deprecated) { typefield->deprecated = true; } - } - - EXPECT(';'); - return NoError(); -} - -CheckedError Parser::ParseString(Value &val, bool use_string_pooling) { - auto s = attribute_; - EXPECT(kTokenStringConstant); - if (use_string_pooling) { - val.constant = NumToString(builder_.CreateSharedString(s).o); - } else { - val.constant = NumToString(builder_.CreateString(s).o); - } - return NoError(); -} - -CheckedError Parser::ParseComma() { - if (!opts.protobuf_ascii_alike) EXPECT(','); - return NoError(); -} - -CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field, - size_t parent_fieldn, - const StructDef *parent_struct_def, - uoffset_t count, bool inside_vector) { - switch (val.type.base_type) { - case BASE_TYPE_UNION: { - FLATBUFFERS_ASSERT(field); - std::string constant; - Vector *vector_of_union_types = nullptr; - // Find corresponding type field we may have already parsed. - for (auto elem = field_stack_.rbegin() + count; - elem != field_stack_.rbegin() + parent_fieldn + count; ++elem) { - auto &type = elem->second->value.type; - if (type.enum_def == val.type.enum_def) { - if (inside_vector) { - if (type.base_type == BASE_TYPE_VECTOR && - type.element == BASE_TYPE_UTYPE) { - // Vector of union type field. - uoffset_t offset; - ECHECK(atot(elem->first.constant.c_str(), *this, &offset)); - vector_of_union_types = reinterpret_cast *>( - builder_.GetCurrentBufferPointer() + builder_.GetSize() - - offset); - break; - } - } else { - if (type.base_type == BASE_TYPE_UTYPE) { - // Union type field. - constant = elem->first.constant; - break; - } - } - } - } - if (constant.empty() && !inside_vector) { - // We haven't seen the type field yet. Sadly a lot of JSON writers - // output these in alphabetical order, meaning it comes after this - // value. So we scan past the value to find it, then come back here. - // We currently don't do this for vectors of unions because the - // scanning/serialization logic would get very complicated. - auto type_name = field->name + UnionTypeFieldSuffix(); - FLATBUFFERS_ASSERT(parent_struct_def); - auto type_field = parent_struct_def->fields.Lookup(type_name); - FLATBUFFERS_ASSERT(type_field); // Guaranteed by ParseField(). - // Remember where we are in the source file, so we can come back here. - auto backup = *static_cast(this); - ECHECK(SkipAnyJsonValue()); // The table. - ECHECK(ParseComma()); - auto next_name = attribute_; - if (Is(kTokenStringConstant)) { - NEXT(); - } else { - EXPECT(kTokenIdentifier); - } - if (next_name == type_name) { - EXPECT(':'); - Value type_val = type_field->value; - ECHECK(ParseAnyValue(type_val, type_field, 0, nullptr, 0)); - constant = type_val.constant; - // Got the information we needed, now rewind: - *static_cast(this) = backup; - } - } - if (constant.empty() && !vector_of_union_types) { - return Error("missing type field for this union value: " + field->name); - } - uint8_t enum_idx; - if (vector_of_union_types) { - enum_idx = vector_of_union_types->Get(count); - } else { - ECHECK(atot(constant.c_str(), *this, &enum_idx)); - } - auto enum_val = val.type.enum_def->ReverseLookup(enum_idx, true); - if (!enum_val) return Error("illegal type id for: " + field->name); - if (enum_val->union_type.base_type == BASE_TYPE_STRUCT) { - ECHECK(ParseTable(*enum_val->union_type.struct_def, &val.constant, - nullptr)); - if (enum_val->union_type.struct_def->fixed) { - // All BASE_TYPE_UNION values are offsets, so turn this into one. - SerializeStruct(*enum_val->union_type.struct_def, val); - builder_.ClearOffsets(); - val.constant = NumToString(builder_.GetSize()); - } - } else if (enum_val->union_type.base_type == BASE_TYPE_STRING) { - ECHECK(ParseString(val, field->shared)); - } else { - FLATBUFFERS_ASSERT(false); - } - break; - } - case BASE_TYPE_STRUCT: - ECHECK(ParseTable(*val.type.struct_def, &val.constant, nullptr)); - break; - case BASE_TYPE_STRING: { - ECHECK(ParseString(val, field->shared)); - break; - } - case BASE_TYPE_VECTOR: { - uoffset_t off; - ECHECK(ParseVector(val.type.VectorType(), &off, field, parent_fieldn)); - val.constant = NumToString(off); - break; - } - case BASE_TYPE_ARRAY: { - ECHECK(ParseArray(val)); - break; - } - case BASE_TYPE_INT: - case BASE_TYPE_UINT: - case BASE_TYPE_LONG: - case BASE_TYPE_ULONG: { - if (field && field->attributes.Lookup("hash") && - (token_ == kTokenIdentifier || token_ == kTokenStringConstant)) { - ECHECK(ParseHash(val, field)); - } else { - ECHECK(ParseSingleValue(field ? &field->name : nullptr, val, false)); - } - break; - } - default: - ECHECK(ParseSingleValue(field ? &field->name : nullptr, val, false)); - break; - } - return NoError(); -} - -void Parser::SerializeStruct(const StructDef &struct_def, const Value &val) { - SerializeStruct(builder_, struct_def, val); -} - -void Parser::SerializeStruct(FlatBufferBuilder &builder, - const StructDef &struct_def, const Value &val) { - FLATBUFFERS_ASSERT(val.constant.length() == struct_def.bytesize); - builder.Align(struct_def.minalign); - builder.PushBytes(reinterpret_cast(val.constant.c_str()), - struct_def.bytesize); - builder.AddStructOffset(val.offset, builder.GetSize()); -} - -template -CheckedError Parser::ParseTableDelimiters(size_t &fieldn, - const StructDef *struct_def, F body) { - // We allow tables both as JSON object{ .. } with field names - // or vector[..] with all fields in order - char terminator = '}'; - bool is_nested_vector = struct_def && Is('['); - if (is_nested_vector) { - NEXT(); - terminator = ']'; - } else { - EXPECT('{'); - } - for (;;) { - if ((!opts.strict_json || !fieldn) && Is(terminator)) break; - std::string name; - if (is_nested_vector) { - if (fieldn >= struct_def->fields.vec.size()) { - return Error("too many unnamed fields in nested array"); - } - name = struct_def->fields.vec[fieldn]->name; - } else { - name = attribute_; - if (Is(kTokenStringConstant)) { - NEXT(); - } else { - EXPECT(opts.strict_json ? kTokenStringConstant : kTokenIdentifier); - } - if (!opts.protobuf_ascii_alike || !(Is('{') || Is('['))) EXPECT(':'); - } - ECHECK(body(name, fieldn, struct_def)); - if (Is(terminator)) break; - ECHECK(ParseComma()); - } - NEXT(); - if (is_nested_vector && fieldn != struct_def->fields.vec.size()) { - return Error("wrong number of unnamed fields in table vector"); - } - return NoError(); -} - -CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value, - uoffset_t *ovalue) { - size_t fieldn_outer = 0; - auto err = ParseTableDelimiters( - fieldn_outer, &struct_def, - [&](const std::string &name, size_t &fieldn, - const StructDef *struct_def_inner) -> CheckedError { - if (name == "$schema") { - ECHECK(Expect(kTokenStringConstant)); - return NoError(); - } - auto field = struct_def_inner->fields.Lookup(name); - if (!field) { - if (!opts.skip_unexpected_fields_in_json) { - return Error("unknown field: " + name); - } else { - ECHECK(SkipAnyJsonValue()); - } - } else { - if (IsIdent("null") && !IsScalar(field->value.type.base_type)) { - ECHECK(Next()); // Ignore this field. - } else { - Value val = field->value; - if (field->flexbuffer) { - flexbuffers::Builder builder(1024, - flexbuffers::BUILDER_FLAG_SHARE_ALL); - ECHECK(ParseFlexBufferValue(&builder)); - builder.Finish(); - // Force alignment for nested flexbuffer - builder_.ForceVectorAlignment(builder.GetSize(), sizeof(uint8_t), - sizeof(largest_scalar_t)); - auto off = builder_.CreateVector(builder.GetBuffer()); - val.constant = NumToString(off.o); - } else if (field->nested_flatbuffer) { - ECHECK( - ParseNestedFlatbuffer(val, field, fieldn, struct_def_inner)); - } else { - ECHECK(Recurse([&]() { - return ParseAnyValue(val, field, fieldn, struct_def_inner, 0); - })); - } - // Hardcoded insertion-sort with error-check. - // If fields are specified in order, then this loop exits - // immediately. - auto elem = field_stack_.rbegin(); - for (; elem != field_stack_.rbegin() + fieldn; ++elem) { - auto existing_field = elem->second; - if (existing_field == field) - return Error("field set more than once: " + field->name); - if (existing_field->value.offset < field->value.offset) break; - } - // Note: elem points to before the insertion point, thus .base() - // points to the correct spot. - field_stack_.insert(elem.base(), std::make_pair(val, field)); - fieldn++; - } - } - return NoError(); - }); - ECHECK(err); - - // Check if all required fields are parsed. - for (auto field_it = struct_def.fields.vec.begin(); - field_it != struct_def.fields.vec.end(); ++field_it) { - auto required_field = *field_it; - if (!required_field->required) { continue; } - bool found = false; - for (auto pf_it = field_stack_.end() - fieldn_outer; - pf_it != field_stack_.end(); ++pf_it) { - auto parsed_field = pf_it->second; - if (parsed_field == required_field) { - found = true; - break; - } - } - if (!found) { - return Error("required field is missing: " + required_field->name + - " in " + struct_def.name); - } - } - - if (struct_def.fixed && fieldn_outer != struct_def.fields.vec.size()) - return Error("struct: wrong number of initializers: " + struct_def.name); - - auto start = struct_def.fixed ? builder_.StartStruct(struct_def.minalign) - : builder_.StartTable(); - - for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1; size; - size /= 2) { - // Go through elements in reverse, since we're building the data backwards. - for (auto it = field_stack_.rbegin(); - it != field_stack_.rbegin() + fieldn_outer; ++it) { - auto &field_value = it->first; - auto field = it->second; - if (!struct_def.sortbysize || - size == SizeOf(field_value.type.base_type)) { - switch (field_value.type.base_type) { - // clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: \ - builder_.Pad(field->padding); \ - if (struct_def.fixed) { \ - CTYPE val; \ - ECHECK(atot(field_value.constant.c_str(), *this, &val)); \ - builder_.PushElement(val); \ - } else { \ - CTYPE val, valdef; \ - ECHECK(atot(field_value.constant.c_str(), *this, &val)); \ - ECHECK(atot(field->value.constant.c_str(), *this, &valdef)); \ - builder_.AddElement(field_value.offset, val, valdef); \ - } \ - break; - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: \ - builder_.Pad(field->padding); \ - if (IsStruct(field->value.type)) { \ - SerializeStruct(*field->value.type.struct_def, field_value); \ - } else { \ - CTYPE val; \ - ECHECK(atot(field_value.constant.c_str(), *this, &val)); \ - builder_.AddOffset(field_value.offset, val); \ - } \ - break; - FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - case BASE_TYPE_ARRAY: - builder_.Pad(field->padding); - builder_.PushBytes( - reinterpret_cast(field_value.constant.c_str()), - InlineSize(field_value.type)); - break; - // clang-format on - } - } - } - } - for (size_t i = 0; i < fieldn_outer; i++) field_stack_.pop_back(); - - if (struct_def.fixed) { - builder_.ClearOffsets(); - builder_.EndStruct(); - FLATBUFFERS_ASSERT(value); - // Temporarily store this struct in the value string, since it is to - // be serialized in-place elsewhere. - value->assign( - reinterpret_cast(builder_.GetCurrentBufferPointer()), - struct_def.bytesize); - builder_.PopBytes(struct_def.bytesize); - FLATBUFFERS_ASSERT(!ovalue); - } else { - auto val = builder_.EndTable(start); - if (ovalue) *ovalue = val; - if (value) *value = NumToString(val); - } - return NoError(); -} - -template -CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) { - EXPECT('['); - for (;;) { - if ((!opts.strict_json || !count) && Is(']')) break; - ECHECK(body(count)); - count++; - if (Is(']')) break; - ECHECK(ParseComma()); - } - NEXT(); - return NoError(); -} - -static bool CompareType(const uint8_t *a, const uint8_t *b, BaseType ftype) { - switch (ftype) { -#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_##ENUM: return ReadScalar(a) < ReadScalar(b); - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) -#undef FLATBUFFERS_TD - case BASE_TYPE_STRING: - // Indirect offset pointer to string pointer. - a += ReadScalar(a); - b += ReadScalar(b); - return *reinterpret_cast(a) < - *reinterpret_cast(b); - default: return false; - } -} - -// See below for why we need our own sort :( -template -void SimpleQsort(T *begin, T *end, size_t width, F comparator, S swapper) { - if (end - begin <= static_cast(width)) return; - auto l = begin + width; - auto r = end; - while (l < r) { - if (comparator(begin, l)) { - r -= width; - swapper(l, r); - } else { - l += width; - } - } - l -= width; - swapper(begin, l); - SimpleQsort(begin, l, width, comparator, swapper); - SimpleQsort(r, end, width, comparator, swapper); -} - -CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue, - FieldDef *field, size_t fieldn) { - uoffset_t count = 0; - auto err = ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError { - Value val; - val.type = type; - ECHECK(Recurse([&]() { - return ParseAnyValue(val, field, fieldn, nullptr, count, true); - })); - field_stack_.push_back(std::make_pair(val, nullptr)); - return NoError(); - }); - ECHECK(err); - - const auto *force_align = field->attributes.Lookup("force_align"); - const size_t align = - force_align ? static_cast(atoi(force_align->constant.c_str())) - : 1; - const size_t len = count * InlineSize(type) / InlineAlignment(type); - const size_t elemsize = InlineAlignment(type); - if (align > 1) { builder_.ForceVectorAlignment(len, elemsize, align); } - - builder_.StartVector(len, elemsize); - for (uoffset_t i = 0; i < count; i++) { - // start at the back, since we're building the data backwards. - auto &val = field_stack_.back().first; - switch (val.type.base_type) { - // clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE,...) \ - case BASE_TYPE_ ## ENUM: \ - if (IsStruct(val.type)) SerializeStruct(*val.type.struct_def, val); \ - else { \ - CTYPE elem; \ - ECHECK(atot(val.constant.c_str(), *this, &elem)); \ - builder_.PushElement(elem); \ - } \ - break; - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - // clang-format on - } - field_stack_.pop_back(); - } - - builder_.ClearOffsets(); - *ovalue = builder_.EndVector(count); - - if (type.base_type == BASE_TYPE_STRUCT && type.struct_def->has_key) { - // We should sort this vector. Find the key first. - const FieldDef *key = nullptr; - for (auto it = type.struct_def->fields.vec.begin(); - it != type.struct_def->fields.vec.end(); ++it) { - if ((*it)->key) { - key = (*it); - break; - } - } - FLATBUFFERS_ASSERT(key); - // Now sort it. - // We can't use std::sort because for structs the size is not known at - // compile time, and for tables our iterators dereference offsets, so can't - // be used to swap elements. - // And we can't use C qsort either, since that would force use to use - // globals, making parsing thread-unsafe. - // So for now, we use SimpleQsort above. - // TODO: replace with something better, preferably not recursive. - voffset_t offset = key->value.offset; - BaseType ftype = key->value.type.base_type; - - if (type.struct_def->fixed) { - auto v = - reinterpret_cast(builder_.GetCurrentBufferPointer()); - SimpleQsort( - v->Data(), v->Data() + v->size() * type.struct_def->bytesize, - type.struct_def->bytesize, - [&](const uint8_t *a, const uint8_t *b) -> bool { - return CompareType(a + offset, b + offset, ftype); - }, - [&](uint8_t *a, uint8_t *b) { - // FIXME: faster? - for (size_t i = 0; i < type.struct_def->bytesize; i++) { - std::swap(a[i], b[i]); - } - }); - } else { - auto v = reinterpret_cast> *>( - builder_.GetCurrentBufferPointer()); - // Here also can't use std::sort. We do have an iterator type for it, - // but it is non-standard as it will dereference the offsets, and thus - // can't be used to swap elements. - SimpleQsort>( - v->data(), v->data() + v->size(), 1, - [&](const Offset
*_a, const Offset
*_b) -> bool { - // Indirect offset pointer to table pointer. - auto a = reinterpret_cast(_a) + - ReadScalar(_a); - auto b = reinterpret_cast(_b) + - ReadScalar(_b); - // Fetch field address from table. - a = reinterpret_cast(a)->GetAddressOf(offset); - b = reinterpret_cast(b)->GetAddressOf(offset); - return CompareType(a, b, ftype); - }, - [&](Offset
*a, Offset
*b) { - // These are serialized offsets, so are relative where they are - // stored in memory, so compute the distance between these pointers: - ptrdiff_t diff = (b - a) * sizeof(Offset
); - FLATBUFFERS_ASSERT(diff >= 0); // Guaranteed by SimpleQsort. - auto udiff = static_cast(diff); - a->o = EndianScalar(ReadScalar(a) - udiff); - b->o = EndianScalar(ReadScalar(b) + udiff); - std::swap(*a, *b); - }); - } - } - return NoError(); -} - -CheckedError Parser::ParseArray(Value &array) { - std::vector stack; - FlatBufferBuilder builder; - const auto &type = array.type.VectorType(); - auto length = array.type.fixed_length; - uoffset_t count = 0; - auto err = ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError { - vector_emplace_back(&stack, Value()); - auto &val = stack.back(); - val.type = type; - if (IsStruct(type)) { - ECHECK(ParseTable(*val.type.struct_def, &val.constant, nullptr)); - } else { - ECHECK(ParseSingleValue(nullptr, val, false)); - } - return NoError(); - }); - ECHECK(err); - if (length != count) return Error("Fixed-length array size is incorrect."); - - for (auto it = stack.rbegin(); it != stack.rend(); ++it) { - auto &val = *it; - // clang-format off - switch (val.type.base_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: \ - if (IsStruct(val.type)) { \ - SerializeStruct(builder, *val.type.struct_def, val); \ - } else { \ - CTYPE elem; \ - ECHECK(atot(val.constant.c_str(), *this, &elem)); \ - builder.PushElement(elem); \ - } \ - break; - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - default: FLATBUFFERS_ASSERT(0); - } - // clang-format on - } - - array.constant.assign( - reinterpret_cast(builder.GetCurrentBufferPointer()), - InlineSize(array.type)); - return NoError(); -} - -CheckedError Parser::ParseNestedFlatbuffer(Value &val, FieldDef *field, - size_t fieldn, - const StructDef *parent_struct_def) { - if (token_ == '[') { // backwards compat for 'legacy' ubyte buffers - ECHECK(ParseAnyValue(val, field, fieldn, parent_struct_def, 0)); - } else { - auto cursor_at_value_begin = cursor_; - ECHECK(SkipAnyJsonValue()); - std::string substring(cursor_at_value_begin - 1, cursor_ - 1); - - // Create and initialize new parser - Parser nested_parser; - FLATBUFFERS_ASSERT(field->nested_flatbuffer); - nested_parser.root_struct_def_ = field->nested_flatbuffer; - nested_parser.enums_ = enums_; - nested_parser.opts = opts; - nested_parser.uses_flexbuffers_ = uses_flexbuffers_; - - // Parse JSON substring into new flatbuffer builder using nested_parser - bool ok = nested_parser.Parse(substring.c_str(), nullptr, nullptr); - - // Clean nested_parser to avoid deleting the elements in - // the SymbolTables on destruction - nested_parser.enums_.dict.clear(); - nested_parser.enums_.vec.clear(); - - if (!ok) { ECHECK(Error(nested_parser.error_)); } - // Force alignment for nested flatbuffer - builder_.ForceVectorAlignment( - nested_parser.builder_.GetSize(), sizeof(uint8_t), - nested_parser.builder_.GetBufferMinAlignment()); - - auto off = builder_.CreateVector(nested_parser.builder_.GetBufferPointer(), - nested_parser.builder_.GetSize()); - val.constant = NumToString(off.o); - } - return NoError(); -} - -CheckedError Parser::ParseMetaData(SymbolTable *attributes) { - if (Is('(')) { - NEXT(); - for (;;) { - auto name = attribute_; - if (false == (Is(kTokenIdentifier) || Is(kTokenStringConstant))) - return Error("attribute name must be either identifier or string: " + - name); - if (known_attributes_.find(name) == known_attributes_.end()) - return Error("user define attributes must be declared before use: " + - name); - NEXT(); - auto e = new Value(); - attributes->Add(name, e); - if (Is(':')) { - NEXT(); - ECHECK(ParseSingleValue(&name, *e, true)); - } - if (Is(')')) { - NEXT(); - break; - } - EXPECT(','); - } - } - return NoError(); -} - -CheckedError Parser::ParseEnumFromString(const Type &type, - std::string *result) { - const auto base_type = - type.enum_def ? type.enum_def->underlying_type.base_type : type.base_type; - if (!IsInteger(base_type)) return Error("not a valid value for this field"); - uint64_t u64 = 0; - for (size_t pos = 0; pos != std::string::npos;) { - const auto delim = attribute_.find_first_of(' ', pos); - const auto last = (std::string::npos == delim); - auto word = attribute_.substr(pos, !last ? delim - pos : std::string::npos); - pos = !last ? delim + 1 : std::string::npos; - const EnumVal *ev = nullptr; - if (type.enum_def) { - ev = type.enum_def->Lookup(word); - } else { - auto dot = word.find_first_of('.'); - if (std::string::npos == dot) - return Error("enum values need to be qualified by an enum type"); - auto enum_def_str = word.substr(0, dot); - const auto enum_def = LookupEnum(enum_def_str); - if (!enum_def) return Error("unknown enum: " + enum_def_str); - auto enum_val_str = word.substr(dot + 1); - ev = enum_def->Lookup(enum_val_str); - } - if (!ev) return Error("unknown enum value: " + word); - u64 |= ev->GetAsUInt64(); - } - *result = IsUnsigned(base_type) ? NumToString(u64) - : NumToString(static_cast(u64)); - return NoError(); -} - -CheckedError Parser::ParseHash(Value &e, FieldDef *field) { - FLATBUFFERS_ASSERT(field); - Value *hash_name = field->attributes.Lookup("hash"); - switch (e.type.base_type) { - case BASE_TYPE_SHORT: { - auto hash = FindHashFunction16(hash_name->constant.c_str()); - int16_t hashed_value = static_cast(hash(attribute_.c_str())); - e.constant = NumToString(hashed_value); - break; - } - case BASE_TYPE_USHORT: { - auto hash = FindHashFunction16(hash_name->constant.c_str()); - uint16_t hashed_value = hash(attribute_.c_str()); - e.constant = NumToString(hashed_value); - break; - } - case BASE_TYPE_INT: { - auto hash = FindHashFunction32(hash_name->constant.c_str()); - int32_t hashed_value = static_cast(hash(attribute_.c_str())); - e.constant = NumToString(hashed_value); - break; - } - case BASE_TYPE_UINT: { - auto hash = FindHashFunction32(hash_name->constant.c_str()); - uint32_t hashed_value = hash(attribute_.c_str()); - e.constant = NumToString(hashed_value); - break; - } - case BASE_TYPE_LONG: { - auto hash = FindHashFunction64(hash_name->constant.c_str()); - int64_t hashed_value = static_cast(hash(attribute_.c_str())); - e.constant = NumToString(hashed_value); - break; - } - case BASE_TYPE_ULONG: { - auto hash = FindHashFunction64(hash_name->constant.c_str()); - uint64_t hashed_value = hash(attribute_.c_str()); - e.constant = NumToString(hashed_value); - break; - } - default: FLATBUFFERS_ASSERT(0); - } - NEXT(); - return NoError(); -} - -CheckedError Parser::TokenError() { - return Error("cannot parse value starting with: " + TokenToStringId(token_)); -} - -// Re-pack helper (ParseSingleValue) to normalize defaults of scalars. -template inline void SingleValueRepack(Value &e, T val) { - // Remove leading zeros. - if (IsInteger(e.type.base_type)) { e.constant = NumToString(val); } -} -#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) -// Normalize defaults NaN to unsigned quiet-NaN(0) if value was parsed from -// hex-float literal. -static inline void SingleValueRepack(Value &e, float val) { - if (val != val) e.constant = "nan"; -} -static inline void SingleValueRepack(Value &e, double val) { - if (val != val) e.constant = "nan"; -} -#endif - -CheckedError Parser::ParseFunction(const std::string *name, Value &e) { - // Copy name, attribute will be changed on NEXT(). - const auto functionname = attribute_; - if (!IsFloat(e.type.base_type)) { - return Error(functionname + ": type of argument mismatch, expecting: " + - kTypeNames[BASE_TYPE_DOUBLE] + - ", found: " + kTypeNames[e.type.base_type] + - ", name: " + (name ? *name : "") + ", value: " + e.constant); - } - NEXT(); - EXPECT('('); - ECHECK(Recurse([&]() { return ParseSingleValue(name, e, false); })); - EXPECT(')'); - // calculate with double precision - double x, y = 0.0; - ECHECK(atot(e.constant.c_str(), *this, &x)); - // clang-format off - auto func_match = false; - #define FLATBUFFERS_FN_DOUBLE(name, op) \ - if (!func_match && functionname == name) { y = op; func_match = true; } - FLATBUFFERS_FN_DOUBLE("deg", x / kPi * 180); - FLATBUFFERS_FN_DOUBLE("rad", x * kPi / 180); - FLATBUFFERS_FN_DOUBLE("sin", sin(x)); - FLATBUFFERS_FN_DOUBLE("cos", cos(x)); - FLATBUFFERS_FN_DOUBLE("tan", tan(x)); - FLATBUFFERS_FN_DOUBLE("asin", asin(x)); - FLATBUFFERS_FN_DOUBLE("acos", acos(x)); - FLATBUFFERS_FN_DOUBLE("atan", atan(x)); - // TODO(wvo): add more useful conversion functions here. - #undef FLATBUFFERS_FN_DOUBLE - // clang-format on - if (true != func_match) { - return Error(std::string("Unknown conversion function: ") + functionname + - ", field name: " + (name ? *name : "") + - ", value: " + e.constant); - } - e.constant = NumToString(y); - return NoError(); -} - -CheckedError Parser::TryTypedValue(const std::string *name, int dtoken, - bool check, Value &e, BaseType req, - bool *destmatch) { - bool match = dtoken == token_; - if (match) { - FLATBUFFERS_ASSERT(*destmatch == false); - *destmatch = true; - e.constant = attribute_; - // Check token match - if (!check) { - if (e.type.base_type == BASE_TYPE_NONE) { - e.type.base_type = req; - } else { - return Error( - std::string("type mismatch: expecting: ") + - kTypeNames[e.type.base_type] + ", found: " + kTypeNames[req] + - ", name: " + (name ? *name : "") + ", value: " + e.constant); - } - } - // The exponent suffix of hexadecimal float-point number is mandatory. - // A hex-integer constant is forbidden as an initializer of float number. - if ((kTokenFloatConstant != dtoken) && IsFloat(e.type.base_type)) { - const auto &s = e.constant; - const auto k = s.find_first_of("0123456789."); - if ((std::string::npos != k) && (s.length() > (k + 1)) && - (s[k] == '0' && is_alpha_char(s[k + 1], 'X')) && - (std::string::npos == s.find_first_of("pP", k + 2))) { - return Error( - "invalid number, the exponent suffix of hexadecimal " - "floating-point literals is mandatory: \"" + - s + "\""); - } - } - NEXT(); - } - return NoError(); -} - -CheckedError Parser::ParseSingleValue(const std::string *name, Value &e, - bool check_now) { - const auto in_type = e.type.base_type; - const auto is_tok_ident = (token_ == kTokenIdentifier); - const auto is_tok_string = (token_ == kTokenStringConstant); - - // First see if this could be a conversion function: - if (is_tok_ident && *cursor_ == '(') { return ParseFunction(name, e); } - - // clang-format off - auto match = false; - - #define IF_ECHECK_(force, dtoken, check, req) \ - if (!match && ((check) || IsConstTrue(force))) \ - ECHECK(TryTypedValue(name, dtoken, check, e, req, &match)) - #define TRY_ECHECK(dtoken, check, req) IF_ECHECK_(false, dtoken, check, req) - #define FORCE_ECHECK(dtoken, check, req) IF_ECHECK_(true, dtoken, check, req) - // clang-format on - - if (is_tok_ident || is_tok_string) { - const auto kTokenStringOrIdent = token_; - // The string type is a most probable type, check it first. - TRY_ECHECK(kTokenStringConstant, in_type == BASE_TYPE_STRING, - BASE_TYPE_STRING); - - // avoid escaped and non-ascii in the string - if (!match && is_tok_string && IsScalar(in_type) && - !attr_is_trivial_ascii_string_) { - return Error( - std::string("type mismatch or invalid value, an initializer of " - "non-string field must be trivial ASCII string: type: ") + - kTypeNames[in_type] + ", name: " + (name ? *name : "") + - ", value: " + attribute_); - } - - // A boolean as true/false. Boolean as Integer check below. - if (!match && IsBool(in_type)) { - auto is_true = attribute_ == "true"; - if (is_true || attribute_ == "false") { - attribute_ = is_true ? "1" : "0"; - // accepts both kTokenStringConstant and kTokenIdentifier - TRY_ECHECK(kTokenStringOrIdent, IsBool(in_type), BASE_TYPE_BOOL); - } - } - // Check if this could be a string/identifier enum value. - // Enum can have only true integer base type. - if (!match && IsInteger(in_type) && !IsBool(in_type) && - IsIdentifierStart(*attribute_.c_str())) { - ECHECK(ParseEnumFromString(e.type, &e.constant)); - NEXT(); - match = true; - } - // Parse a float/integer number from the string. - if (!match) check_now = true; // Re-pack if parsed from string literal. - // A "scalar-in-string" value needs extra checks. - if (!match && is_tok_string && IsScalar(in_type)) { - // Strip trailing whitespaces from attribute_. - auto last_non_ws = attribute_.find_last_not_of(' '); - if (std::string::npos != last_non_ws) attribute_.resize(last_non_ws + 1); - if (IsFloat(e.type.base_type)) { - // The functions strtod() and strtof() accept both 'nan' and - // 'nan(number)' literals. While 'nan(number)' is rejected by the parser - // as an unsupported function if is_tok_ident is true. - if (attribute_.find_last_of(')') != std::string::npos) { - return Error("invalid number: " + attribute_); - } - } - } - // Float numbers or nan, inf, pi, etc. - TRY_ECHECK(kTokenStringOrIdent, IsFloat(in_type), BASE_TYPE_FLOAT); - // An integer constant in string. - TRY_ECHECK(kTokenStringOrIdent, IsInteger(in_type), BASE_TYPE_INT); - // Unknown tokens will be interpreted as string type. - // An attribute value may be a scalar or string constant. - FORCE_ECHECK(kTokenStringConstant, in_type == BASE_TYPE_STRING, - BASE_TYPE_STRING); - } else { - // Try a float number. - TRY_ECHECK(kTokenFloatConstant, IsFloat(in_type), BASE_TYPE_FLOAT); - // Integer token can init any scalar (integer of float). - FORCE_ECHECK(kTokenIntegerConstant, IsScalar(in_type), BASE_TYPE_INT); - } -#undef FORCE_ECHECK -#undef TRY_ECHECK -#undef IF_ECHECK_ - - if (!match) { - std::string msg; - msg += "Cannot assign token starting with '" + TokenToStringId(token_) + - "' to value of <" + std::string(kTypeNames[in_type]) + "> type."; - return Error(msg); - } - const auto match_type = e.type.base_type; // may differ from in_type - // The check_now flag must be true when parse a fbs-schema. - // This flag forces to check default scalar values or metadata of field. - // For JSON parser the flag should be false. - // If it is set for JSON each value will be checked twice (see ParseTable). - if (check_now && IsScalar(match_type)) { - // clang-format off - switch (match_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_ ## ENUM: {\ - CTYPE val; \ - ECHECK(atot(e.constant.c_str(), *this, &val)); \ - SingleValueRepack(e, val); \ - break; } - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - default: break; - } - // clang-format on - } - return NoError(); -} - -StructDef *Parser::LookupCreateStruct(const std::string &name, - bool create_if_new, bool definition) { - std::string qualified_name = current_namespace_->GetFullyQualifiedName(name); - // See if it exists pre-declared by an unqualified use. - auto struct_def = LookupStruct(name); - if (struct_def && struct_def->predecl) { - if (definition) { - // Make sure it has the current namespace, and is registered under its - // qualified name. - struct_def->defined_namespace = current_namespace_; - structs_.Move(name, qualified_name); - } - return struct_def; - } - // See if it exists pre-declared by an qualified use. - struct_def = LookupStruct(qualified_name); - if (struct_def && struct_def->predecl) { - if (definition) { - // Make sure it has the current namespace. - struct_def->defined_namespace = current_namespace_; - } - return struct_def; - } - if (!definition) { - // Search thru parent namespaces. - for (size_t components = current_namespace_->components.size(); - components && !struct_def; components--) { - struct_def = LookupStruct( - current_namespace_->GetFullyQualifiedName(name, components - 1)); - } - } - if (!struct_def && create_if_new) { - struct_def = new StructDef(); - if (definition) { - structs_.Add(qualified_name, struct_def); - struct_def->name = name; - struct_def->defined_namespace = current_namespace_; - } else { - // Not a definition. - // Rather than failing, we create a "pre declared" StructDef, due to - // circular references, and check for errors at the end of parsing. - // It is defined in the current namespace, as the best guess what the - // final namespace will be. - structs_.Add(name, struct_def); - struct_def->name = name; - struct_def->defined_namespace = current_namespace_; - struct_def->original_location.reset( - new std::string(file_being_parsed_ + ":" + NumToString(line_))); - } - } - return struct_def; -} - -const EnumVal *EnumDef::MinValue() const { - return vals.vec.empty() ? nullptr : vals.vec.front(); -} -const EnumVal *EnumDef::MaxValue() const { - return vals.vec.empty() ? nullptr : vals.vec.back(); -} - -template static uint64_t EnumDistanceImpl(T e1, T e2) { - if (e1 < e2) { std::swap(e1, e2); } // use std for scalars - // Signed overflow may occur, use unsigned calculation. - // The unsigned overflow is well-defined by C++ standard (modulo 2^n). - return static_cast(e1) - static_cast(e2); -} - -uint64_t EnumDef::Distance(const EnumVal *v1, const EnumVal *v2) const { - return IsUInt64() ? EnumDistanceImpl(v1->GetAsUInt64(), v2->GetAsUInt64()) - : EnumDistanceImpl(v1->GetAsInt64(), v2->GetAsInt64()); -} - -std::string EnumDef::AllFlags() const { - FLATBUFFERS_ASSERT(attributes.Lookup("bit_flags")); - uint64_t u64 = 0; - for (auto it = Vals().begin(); it != Vals().end(); ++it) { - u64 |= (*it)->GetAsUInt64(); - } - return IsUInt64() ? NumToString(u64) : NumToString(static_cast(u64)); -} - -EnumVal *EnumDef::ReverseLookup(int64_t enum_idx, - bool skip_union_default) const { - auto skip_first = static_cast(is_union && skip_union_default); - for (auto it = Vals().begin() + skip_first; it != Vals().end(); ++it) { - if ((*it)->GetAsInt64() == enum_idx) { return *it; } - } - return nullptr; -} - -EnumVal *EnumDef::FindByValue(const std::string &constant) const { - int64_t i64; - auto done = false; - if (IsUInt64()) { - uint64_t u64; // avoid reinterpret_cast of pointers - done = StringToNumber(constant.c_str(), &u64); - i64 = static_cast(u64); - } else { - done = StringToNumber(constant.c_str(), &i64); - } - FLATBUFFERS_ASSERT(done); - if (!done) return nullptr; - return ReverseLookup(i64, false); -} - -void EnumDef::SortByValue() { - auto &v = vals.vec; - if (IsUInt64()) - std::sort(v.begin(), v.end(), [](const EnumVal *e1, const EnumVal *e2) { - return e1->GetAsUInt64() < e2->GetAsUInt64(); - }); - else - std::sort(v.begin(), v.end(), [](const EnumVal *e1, const EnumVal *e2) { - return e1->GetAsInt64() < e2->GetAsInt64(); - }); -} - -void EnumDef::RemoveDuplicates() { - // This method depends form SymbolTable implementation! - // 1) vals.vec - owner (raw pointer) - // 2) vals.dict - access map - auto first = vals.vec.begin(); - auto last = vals.vec.end(); - if (first == last) return; - auto result = first; - while (++first != last) { - if ((*result)->value != (*first)->value) { - *(++result) = *first; - } else { - auto ev = *first; - for (auto it = vals.dict.begin(); it != vals.dict.end(); ++it) { - if (it->second == ev) it->second = *result; // reassign - } - delete ev; // delete enum value - *first = nullptr; - } - } - vals.vec.erase(++result, last); -} - -template void EnumDef::ChangeEnumValue(EnumVal *ev, T new_value) { - ev->value = static_cast(new_value); -} - -namespace EnumHelper { -template struct EnumValType { typedef int64_t type; }; -template<> struct EnumValType { typedef uint64_t type; }; -} // namespace EnumHelper - -struct EnumValBuilder { - EnumVal *CreateEnumerator(const std::string &ev_name) { - FLATBUFFERS_ASSERT(!temp); - auto first = enum_def.vals.vec.empty(); - user_value = first; - temp = new EnumVal(ev_name, first ? 0 : enum_def.vals.vec.back()->value); - return temp; - } - - EnumVal *CreateEnumerator(const std::string &ev_name, int64_t val) { - FLATBUFFERS_ASSERT(!temp); - user_value = true; - temp = new EnumVal(ev_name, val); - return temp; - } - - FLATBUFFERS_CHECKED_ERROR AcceptEnumerator(const std::string &name) { - FLATBUFFERS_ASSERT(temp); - ECHECK(ValidateValue(&temp->value, false == user_value)); - FLATBUFFERS_ASSERT((temp->union_type.enum_def == nullptr) || - (temp->union_type.enum_def == &enum_def)); - auto not_unique = enum_def.vals.Add(name, temp); - temp = nullptr; - if (not_unique) return parser.Error("enum value already exists: " + name); - return NoError(); - } - - FLATBUFFERS_CHECKED_ERROR AcceptEnumerator() { - return AcceptEnumerator(temp->name); - } - - FLATBUFFERS_CHECKED_ERROR AssignEnumeratorValue(const std::string &value) { - user_value = true; - auto fit = false; - if (enum_def.IsUInt64()) { - uint64_t u64; - fit = StringToNumber(value.c_str(), &u64); - temp->value = static_cast(u64); // well-defined since C++20. - } else { - int64_t i64; - fit = StringToNumber(value.c_str(), &i64); - temp->value = i64; - } - if (!fit) return parser.Error("enum value does not fit, \"" + value + "\""); - return NoError(); - } - - template - inline FLATBUFFERS_CHECKED_ERROR ValidateImpl(int64_t *ev, int m) { - typedef typename EnumHelper::EnumValType::type T; // int64_t or uint64_t - static_assert(sizeof(T) == sizeof(int64_t), "invalid EnumValType"); - const auto v = static_cast(*ev); - auto up = static_cast((flatbuffers::numeric_limits::max)()); - auto dn = static_cast((flatbuffers::numeric_limits::lowest)()); - if (v < dn || v > (up - m)) { - return parser.Error("enum value does not fit, \"" + NumToString(v) + - (m ? " + 1\"" : "\"") + " out of " + - TypeToIntervalString()); - } - *ev = static_cast(v + m); // well-defined since C++20. - return NoError(); - } - - FLATBUFFERS_CHECKED_ERROR ValidateValue(int64_t *ev, bool next) { - // clang-format off - switch (enum_def.underlying_type.base_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - case BASE_TYPE_##ENUM: { \ - if (!IsInteger(BASE_TYPE_##ENUM)) break; \ - return ValidateImpl(ev, next ? 1 : 0); \ - } - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - default: break; - } - // clang-format on - return parser.Error("fatal: invalid enum underlying type"); - } - - EnumValBuilder(Parser &_parser, EnumDef &_enum_def) - : parser(_parser), - enum_def(_enum_def), - temp(nullptr), - user_value(false) {} - - ~EnumValBuilder() { delete temp; } - - Parser &parser; - EnumDef &enum_def; - EnumVal *temp; - bool user_value; -}; - -CheckedError Parser::ParseEnum(const bool is_union, EnumDef **dest) { - std::vector enum_comment = doc_comment_; - NEXT(); - std::string enum_name = attribute_; - EXPECT(kTokenIdentifier); - EnumDef *enum_def; - ECHECK(StartEnum(enum_name, is_union, &enum_def)); - enum_def->doc_comment = enum_comment; - if (!is_union && !opts.proto_mode) { - // Give specialized error message, since this type spec used to - // be optional in the first FlatBuffers release. - if (!Is(':')) { - return Error( - "must specify the underlying integer type for this" - " enum (e.g. \': short\', which was the default)."); - } else { - NEXT(); - } - // Specify the integer type underlying this enum. - ECHECK(ParseType(enum_def->underlying_type)); - if (!IsInteger(enum_def->underlying_type.base_type) || - IsBool(enum_def->underlying_type.base_type)) - return Error("underlying enum type must be integral"); - // Make this type refer back to the enum it was derived from. - enum_def->underlying_type.enum_def = enum_def; - } - ECHECK(ParseMetaData(&enum_def->attributes)); - const auto underlying_type = enum_def->underlying_type.base_type; - if (enum_def->attributes.Lookup("bit_flags") && - !IsUnsigned(underlying_type)) { - // todo: Convert to the Error in the future? - Warning("underlying type of bit_flags enum must be unsigned"); - } - EnumValBuilder evb(*this, *enum_def); - EXPECT('{'); - // A lot of code generatos expect that an enum is not-empty. - if ((is_union || Is('}')) && !opts.proto_mode) { - evb.CreateEnumerator("NONE"); - ECHECK(evb.AcceptEnumerator()); - } - std::set> union_types; - while (!Is('}')) { - if (opts.proto_mode && attribute_ == "option") { - ECHECK(ParseProtoOption()); - } else { - auto &ev = *evb.CreateEnumerator(attribute_); - auto full_name = ev.name; - ev.doc_comment = doc_comment_; - EXPECT(kTokenIdentifier); - if (is_union) { - ECHECK(ParseNamespacing(&full_name, &ev.name)); - if (opts.union_value_namespacing) { - // Since we can't namespace the actual enum identifiers, turn - // namespace parts into part of the identifier. - ev.name = full_name; - std::replace(ev.name.begin(), ev.name.end(), '.', '_'); - } - if (Is(':')) { - NEXT(); - ECHECK(ParseType(ev.union_type)); - if (ev.union_type.base_type != BASE_TYPE_STRUCT && - ev.union_type.base_type != BASE_TYPE_STRING) - return Error("union value type may only be table/struct/string"); - } else { - ev.union_type = Type(BASE_TYPE_STRUCT, LookupCreateStruct(full_name)); - } - if (!enum_def->uses_multiple_type_instances) { - auto ins = union_types.insert(std::make_pair( - ev.union_type.base_type, ev.union_type.struct_def)); - enum_def->uses_multiple_type_instances = (false == ins.second); - } - } - - if (Is('=')) { - NEXT(); - ECHECK(evb.AssignEnumeratorValue(attribute_)); - EXPECT(kTokenIntegerConstant); - } - - ECHECK(evb.AcceptEnumerator()); - - if (opts.proto_mode && Is('[')) { - NEXT(); - // ignore attributes on enums. - while (token_ != ']') NEXT(); - NEXT(); - } - } - if (!Is(opts.proto_mode ? ';' : ',')) break; - NEXT(); - } - EXPECT('}'); - - // At this point, the enum can be empty if input is invalid proto-file. - if (!enum_def->size()) - return Error("incomplete enum declaration, values not found"); - - if (enum_def->attributes.Lookup("bit_flags")) { - const auto base_width = static_cast(8 * SizeOf(underlying_type)); - for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end(); - ++it) { - auto ev = *it; - const auto u = ev->GetAsUInt64(); - // Stop manipulations with the sign. - if (!IsUnsigned(underlying_type) && u == (base_width - 1)) - return Error("underlying type of bit_flags enum must be unsigned"); - if (u >= base_width) - return Error("bit flag out of range of underlying integral type"); - enum_def->ChangeEnumValue(ev, 1ULL << u); - } - } - - enum_def->SortByValue(); // Must be sorted to use MinValue/MaxValue. - - // Ensure enum value uniqueness. - auto prev_it = enum_def->Vals().begin(); - for (auto it = prev_it + 1; it != enum_def->Vals().end(); ++it) { - auto prev_ev = *prev_it; - auto ev = *it; - if (prev_ev->GetAsUInt64() == ev->GetAsUInt64()) - return Error("all enum values must be unique: " + prev_ev->name + - " and " + ev->name + " are both " + - NumToString(ev->GetAsInt64())); - } - - if (dest) *dest = enum_def; - types_.Add(current_namespace_->GetFullyQualifiedName(enum_def->name), - new Type(BASE_TYPE_UNION, nullptr, enum_def)); - return NoError(); -} - -CheckedError Parser::StartStruct(const std::string &name, StructDef **dest) { - auto &struct_def = *LookupCreateStruct(name, true, true); - if (!struct_def.predecl) return Error("datatype already exists: " + name); - struct_def.predecl = false; - struct_def.name = name; - struct_def.file = file_being_parsed_; - // Move this struct to the back of the vector just in case it was predeclared, - // to preserve declaration order. - *std::remove(structs_.vec.begin(), structs_.vec.end(), &struct_def) = - &struct_def; - *dest = &struct_def; - return NoError(); -} - -CheckedError Parser::CheckClash(std::vector &fields, - StructDef *struct_def, const char *suffix, - BaseType basetype) { - auto len = strlen(suffix); - for (auto it = fields.begin(); it != fields.end(); ++it) { - auto &fname = (*it)->name; - if (fname.length() > len && - fname.compare(fname.length() - len, len, suffix) == 0 && - (*it)->value.type.base_type != BASE_TYPE_UTYPE) { - auto field = - struct_def->fields.Lookup(fname.substr(0, fname.length() - len)); - if (field && field->value.type.base_type == basetype) - return Error("Field " + fname + - " would clash with generated functions for field " + - field->name); - } - } - return NoError(); -} - -bool Parser::SupportsAdvancedUnionFeatures() const { - return opts.lang_to_generate != 0 && - (opts.lang_to_generate & - ~(IDLOptions::kCpp | IDLOptions::kJs | IDLOptions::kTs | - IDLOptions::kPhp | IDLOptions::kJava | IDLOptions::kCSharp | - IDLOptions::kKotlin | IDLOptions::kBinary | IDLOptions::kSwift)) == - 0; -} - -bool Parser::SupportsAdvancedArrayFeatures() const { - return (opts.lang_to_generate & - ~(IDLOptions::kCpp | IDLOptions::kPython | IDLOptions::kJava | - IDLOptions::kCSharp | IDLOptions::kJsonSchema | IDLOptions::kJson | - IDLOptions::kBinary)) == 0; -} - -Namespace *Parser::UniqueNamespace(Namespace *ns) { - for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) { - if (ns->components == (*it)->components) { - delete ns; - return *it; - } - } - namespaces_.push_back(ns); - return ns; -} - -std::string Parser::UnqualifiedName(const std::string &full_qualified_name) { - Namespace *ns = new Namespace(); - - std::size_t current, previous = 0; - current = full_qualified_name.find('.'); - while (current != std::string::npos) { - ns->components.push_back( - full_qualified_name.substr(previous, current - previous)); - previous = current + 1; - current = full_qualified_name.find('.', previous); - } - current_namespace_ = UniqueNamespace(ns); - return full_qualified_name.substr(previous, current - previous); -} - -static bool compareFieldDefs(const FieldDef *a, const FieldDef *b) { - auto a_id = atoi(a->attributes.Lookup("id")->constant.c_str()); - auto b_id = atoi(b->attributes.Lookup("id")->constant.c_str()); - return a_id < b_id; -} - -CheckedError Parser::ParseDecl() { - std::vector dc = doc_comment_; - bool fixed = IsIdent("struct"); - if (!fixed && !IsIdent("table")) return Error("declaration expected"); - NEXT(); - std::string name = attribute_; - EXPECT(kTokenIdentifier); - StructDef *struct_def; - ECHECK(StartStruct(name, &struct_def)); - struct_def->doc_comment = dc; - struct_def->fixed = fixed; - ECHECK(ParseMetaData(&struct_def->attributes)); - struct_def->sortbysize = - struct_def->attributes.Lookup("original_order") == nullptr && !fixed; - EXPECT('{'); - while (token_ != '}') ECHECK(ParseField(*struct_def)); - auto force_align = struct_def->attributes.Lookup("force_align"); - if (fixed) { - if (force_align) { - auto align = static_cast(atoi(force_align->constant.c_str())); - if (force_align->type.base_type != BASE_TYPE_INT || - align < struct_def->minalign || align > FLATBUFFERS_MAX_ALIGNMENT || - align & (align - 1)) - return Error( - "force_align must be a power of two integer ranging from the" - "struct\'s natural alignment to " + - NumToString(FLATBUFFERS_MAX_ALIGNMENT)); - struct_def->minalign = align; - } - if (!struct_def->bytesize) return Error("size 0 structs not allowed"); - } - struct_def->PadLastField(struct_def->minalign); - // Check if this is a table that has manual id assignments - auto &fields = struct_def->fields.vec; - if (!fixed && fields.size()) { - size_t num_id_fields = 0; - for (auto it = fields.begin(); it != fields.end(); ++it) { - if ((*it)->attributes.Lookup("id")) num_id_fields++; - } - // If any fields have ids.. - if (num_id_fields) { - // Then all fields must have them. - if (num_id_fields != fields.size()) - return Error( - "either all fields or no fields must have an 'id' attribute"); - // Simply sort by id, then the fields are the same as if no ids had - // been specified. - std::sort(fields.begin(), fields.end(), compareFieldDefs); - // Verify we have a contiguous set, and reassign vtable offsets. - for (int i = 0; i < static_cast(fields.size()); i++) { - if (i != atoi(fields[i]->attributes.Lookup("id")->constant.c_str())) - return Error("field id\'s must be consecutive from 0, id " + - NumToString(i) + " missing or set twice"); - fields[i]->value.offset = FieldIndexToOffset(static_cast(i)); - } - } - } - - ECHECK( - CheckClash(fields, struct_def, UnionTypeFieldSuffix(), BASE_TYPE_UNION)); - ECHECK(CheckClash(fields, struct_def, "Type", BASE_TYPE_UNION)); - ECHECK(CheckClash(fields, struct_def, "_length", BASE_TYPE_VECTOR)); - ECHECK(CheckClash(fields, struct_def, "Length", BASE_TYPE_VECTOR)); - ECHECK(CheckClash(fields, struct_def, "_byte_vector", BASE_TYPE_STRING)); - ECHECK(CheckClash(fields, struct_def, "ByteVector", BASE_TYPE_STRING)); - EXPECT('}'); - types_.Add(current_namespace_->GetFullyQualifiedName(struct_def->name), - new Type(BASE_TYPE_STRUCT, struct_def, nullptr)); - return NoError(); -} - -CheckedError Parser::ParseService() { - std::vector service_comment = doc_comment_; - NEXT(); - auto service_name = attribute_; - EXPECT(kTokenIdentifier); - auto &service_def = *new ServiceDef(); - service_def.name = service_name; - service_def.file = file_being_parsed_; - service_def.doc_comment = service_comment; - service_def.defined_namespace = current_namespace_; - if (services_.Add(current_namespace_->GetFullyQualifiedName(service_name), - &service_def)) - return Error("service already exists: " + service_name); - ECHECK(ParseMetaData(&service_def.attributes)); - EXPECT('{'); - do { - std::vector doc_comment = doc_comment_; - auto rpc_name = attribute_; - EXPECT(kTokenIdentifier); - EXPECT('('); - Type reqtype, resptype; - ECHECK(ParseTypeIdent(reqtype)); - EXPECT(')'); - EXPECT(':'); - ECHECK(ParseTypeIdent(resptype)); - if (reqtype.base_type != BASE_TYPE_STRUCT || reqtype.struct_def->fixed || - resptype.base_type != BASE_TYPE_STRUCT || resptype.struct_def->fixed) - return Error("rpc request and response types must be tables"); - auto &rpc = *new RPCCall(); - rpc.name = rpc_name; - rpc.request = reqtype.struct_def; - rpc.response = resptype.struct_def; - rpc.doc_comment = doc_comment; - if (service_def.calls.Add(rpc_name, &rpc)) - return Error("rpc already exists: " + rpc_name); - ECHECK(ParseMetaData(&rpc.attributes)); - EXPECT(';'); - } while (token_ != '}'); - NEXT(); - return NoError(); -} - -bool Parser::SetRootType(const char *name) { - root_struct_def_ = LookupStruct(name); - if (!root_struct_def_) - root_struct_def_ = - LookupStruct(current_namespace_->GetFullyQualifiedName(name)); - return root_struct_def_ != nullptr; -} - -void Parser::MarkGenerated() { - // This function marks all existing definitions as having already - // been generated, which signals no code for included files should be - // generated. - for (auto it = enums_.vec.begin(); it != enums_.vec.end(); ++it) { - (*it)->generated = true; - } - for (auto it = structs_.vec.begin(); it != structs_.vec.end(); ++it) { - if (!(*it)->predecl) { (*it)->generated = true; } - } - for (auto it = services_.vec.begin(); it != services_.vec.end(); ++it) { - (*it)->generated = true; - } -} - -CheckedError Parser::ParseNamespace() { - NEXT(); - auto ns = new Namespace(); - namespaces_.push_back(ns); // Store it here to not leak upon error. - if (token_ != ';') { - for (;;) { - ns->components.push_back(attribute_); - EXPECT(kTokenIdentifier); - if (Is('.')) NEXT() else break; - } - } - namespaces_.pop_back(); - current_namespace_ = UniqueNamespace(ns); - EXPECT(';'); - return NoError(); -} - -// Best effort parsing of .proto declarations, with the aim to turn them -// in the closest corresponding FlatBuffer equivalent. -// We parse everything as identifiers instead of keywords, since we don't -// want protobuf keywords to become invalid identifiers in FlatBuffers. -CheckedError Parser::ParseProtoDecl() { - bool isextend = IsIdent("extend"); - if (IsIdent("package")) { - // These are identical in syntax to FlatBuffer's namespace decl. - ECHECK(ParseNamespace()); - } else if (IsIdent("message") || isextend) { - std::vector struct_comment = doc_comment_; - NEXT(); - StructDef *struct_def = nullptr; - Namespace *parent_namespace = nullptr; - if (isextend) { - if (Is('.')) NEXT(); // qualified names may start with a . ? - auto id = attribute_; - EXPECT(kTokenIdentifier); - ECHECK(ParseNamespacing(&id, nullptr)); - struct_def = LookupCreateStruct(id, false); - if (!struct_def) - return Error("cannot extend unknown message type: " + id); - } else { - std::string name = attribute_; - EXPECT(kTokenIdentifier); - ECHECK(StartStruct(name, &struct_def)); - // Since message definitions can be nested, we create a new namespace. - auto ns = new Namespace(); - // Copy of current namespace. - *ns = *current_namespace_; - // But with current message name. - ns->components.push_back(name); - ns->from_table++; - parent_namespace = current_namespace_; - current_namespace_ = UniqueNamespace(ns); - } - struct_def->doc_comment = struct_comment; - ECHECK(ParseProtoFields(struct_def, isextend, false)); - if (!isextend) { current_namespace_ = parent_namespace; } - if (Is(';')) NEXT(); - } else if (IsIdent("enum")) { - // These are almost the same, just with different terminator: - EnumDef *enum_def; - ECHECK(ParseEnum(false, &enum_def)); - if (Is(';')) NEXT(); - // Temp: remove any duplicates, as .fbs files can't handle them. - enum_def->RemoveDuplicates(); - } else if (IsIdent("syntax")) { // Skip these. - NEXT(); - EXPECT('='); - EXPECT(kTokenStringConstant); - EXPECT(';'); - } else if (IsIdent("option")) { // Skip these. - ECHECK(ParseProtoOption()); - EXPECT(';'); - } else if (IsIdent("service")) { // Skip these. - NEXT(); - EXPECT(kTokenIdentifier); - ECHECK(ParseProtoCurliesOrIdent()); - } else { - return Error("don\'t know how to parse .proto declaration starting with " + - TokenToStringId(token_)); - } - return NoError(); -} - -CheckedError Parser::StartEnum(const std::string &enum_name, bool is_union, - EnumDef **dest) { - auto &enum_def = *new EnumDef(); - enum_def.name = enum_name; - enum_def.file = file_being_parsed_; - enum_def.doc_comment = doc_comment_; - enum_def.is_union = is_union; - enum_def.defined_namespace = current_namespace_; - if (enums_.Add(current_namespace_->GetFullyQualifiedName(enum_name), - &enum_def)) - return Error("enum already exists: " + enum_name); - enum_def.underlying_type.base_type = - is_union ? BASE_TYPE_UTYPE : BASE_TYPE_INT; - enum_def.underlying_type.enum_def = &enum_def; - if (dest) *dest = &enum_def; - return NoError(); -} - -CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend, - bool inside_oneof) { - EXPECT('{'); - while (token_ != '}') { - if (IsIdent("message") || IsIdent("extend") || IsIdent("enum")) { - // Nested declarations. - ECHECK(ParseProtoDecl()); - } else if (IsIdent("extensions")) { // Skip these. - NEXT(); - EXPECT(kTokenIntegerConstant); - if (Is(kTokenIdentifier)) { - NEXT(); // to - NEXT(); // num - } - EXPECT(';'); - } else if (IsIdent("option")) { // Skip these. - ECHECK(ParseProtoOption()); - EXPECT(';'); - } else if (IsIdent("reserved")) { // Skip these. - NEXT(); - while (!Is(';')) { NEXT(); } // A variety of formats, just skip. - NEXT(); - } else { - std::vector field_comment = doc_comment_; - // Parse the qualifier. - bool required = false; - bool repeated = false; - bool oneof = false; - if (!inside_oneof) { - if (IsIdent("optional")) { - // This is the default. - NEXT(); - } else if (IsIdent("required")) { - required = true; - NEXT(); - } else if (IsIdent("repeated")) { - repeated = true; - NEXT(); - } else if (IsIdent("oneof")) { - oneof = true; - NEXT(); - } else { - // can't error, proto3 allows decls without any of the above. - } - } - StructDef *anonymous_struct = nullptr; - EnumDef *oneof_union = nullptr; - Type type; - if (IsIdent("group") || oneof) { - if (!oneof) NEXT(); - if (oneof && opts.proto_oneof_union) { - auto name = MakeCamel(attribute_, true) + "Union"; - ECHECK(StartEnum(name, true, &oneof_union)); - type = Type(BASE_TYPE_UNION, nullptr, oneof_union); - } else { - auto name = "Anonymous" + NumToString(anonymous_counter++); - ECHECK(StartStruct(name, &anonymous_struct)); - type = Type(BASE_TYPE_STRUCT, anonymous_struct); - } - } else { - ECHECK(ParseTypeFromProtoType(&type)); - } - // Repeated elements get mapped to a vector. - if (repeated) { - type.element = type.base_type; - type.base_type = BASE_TYPE_VECTOR; - if (type.element == BASE_TYPE_VECTOR) { - // We have a vector or vectors, which FlatBuffers doesn't support. - // For now make it a vector of string (since the source is likely - // "repeated bytes"). - // TODO(wvo): A better solution would be to wrap this in a table. - type.element = BASE_TYPE_STRING; - } - } - std::string name = attribute_; - EXPECT(kTokenIdentifier); - if (!oneof) { - // Parse the field id. Since we're just translating schemas, not - // any kind of binary compatibility, we can safely ignore these, and - // assign our own. - EXPECT('='); - EXPECT(kTokenIntegerConstant); - } - FieldDef *field = nullptr; - if (isextend) { - // We allow a field to be re-defined when extending. - // TODO: are there situations where that is problematic? - field = struct_def->fields.Lookup(name); - } - if (!field) ECHECK(AddField(*struct_def, name, type, &field)); - field->doc_comment = field_comment; - if (!IsScalar(type.base_type)) field->required = required; - // See if there's a default specified. - if (Is('[')) { - NEXT(); - for (;;) { - auto key = attribute_; - ECHECK(ParseProtoKey()); - EXPECT('='); - auto val = attribute_; - ECHECK(ParseProtoCurliesOrIdent()); - if (key == "default") { - // Temp: skip non-numeric and non-boolean defaults (enums). - auto numeric = strpbrk(val.c_str(), "0123456789-+."); - if (IsScalar(type.base_type) && numeric == val.c_str()) { - field->value.constant = val; - } else if (val == "true") { - field->value.constant = val; - } // "false" is default, no need to handle explicitly. - } else if (key == "deprecated") { - field->deprecated = val == "true"; - } - if (!Is(',')) break; - NEXT(); - } - EXPECT(']'); - } - if (anonymous_struct) { - ECHECK(ParseProtoFields(anonymous_struct, false, oneof)); - if (Is(';')) NEXT(); - } else if (oneof_union) { - // Parse into a temporary StructDef, then transfer fields into an - // EnumDef describing the oneof as a union. - StructDef oneof_struct; - ECHECK(ParseProtoFields(&oneof_struct, false, oneof)); - if (Is(';')) NEXT(); - for (auto field_it = oneof_struct.fields.vec.begin(); - field_it != oneof_struct.fields.vec.end(); ++field_it) { - const auto &oneof_field = **field_it; - const auto &oneof_type = oneof_field.value.type; - if (oneof_type.base_type != BASE_TYPE_STRUCT || - !oneof_type.struct_def || oneof_type.struct_def->fixed) - return Error("oneof '" + name + - "' cannot be mapped to a union because member '" + - oneof_field.name + "' is not a table type."); - EnumValBuilder evb(*this, *oneof_union); - auto ev = evb.CreateEnumerator(oneof_type.struct_def->name); - ev->union_type = oneof_type; - ev->doc_comment = oneof_field.doc_comment; - ECHECK(evb.AcceptEnumerator(oneof_field.name)); - } - } else { - EXPECT(';'); - } - } - } - NEXT(); - return NoError(); -} - -CheckedError Parser::ParseProtoKey() { - if (token_ == '(') { - NEXT(); - // Skip "(a.b)" style custom attributes. - while (token_ == '.' || token_ == kTokenIdentifier) NEXT(); - EXPECT(')'); - while (Is('.')) { - NEXT(); - EXPECT(kTokenIdentifier); - } - } else { - EXPECT(kTokenIdentifier); - } - return NoError(); -} - -CheckedError Parser::ParseProtoCurliesOrIdent() { - if (Is('{')) { - NEXT(); - for (int nesting = 1; nesting;) { - if (token_ == '{') - nesting++; - else if (token_ == '}') - nesting--; - NEXT(); - } - } else { - NEXT(); // Any single token. - } - return NoError(); -} - -CheckedError Parser::ParseProtoOption() { - NEXT(); - ECHECK(ParseProtoKey()); - EXPECT('='); - ECHECK(ParseProtoCurliesOrIdent()); - return NoError(); -} - -// Parse a protobuf type, and map it to the corresponding FlatBuffer one. -CheckedError Parser::ParseTypeFromProtoType(Type *type) { - struct type_lookup { - const char *proto_type; - BaseType fb_type, element; - }; - static type_lookup lookup[] = { - { "float", BASE_TYPE_FLOAT, BASE_TYPE_NONE }, - { "double", BASE_TYPE_DOUBLE, BASE_TYPE_NONE }, - { "int32", BASE_TYPE_INT, BASE_TYPE_NONE }, - { "int64", BASE_TYPE_LONG, BASE_TYPE_NONE }, - { "uint32", BASE_TYPE_UINT, BASE_TYPE_NONE }, - { "uint64", BASE_TYPE_ULONG, BASE_TYPE_NONE }, - { "sint32", BASE_TYPE_INT, BASE_TYPE_NONE }, - { "sint64", BASE_TYPE_LONG, BASE_TYPE_NONE }, - { "fixed32", BASE_TYPE_UINT, BASE_TYPE_NONE }, - { "fixed64", BASE_TYPE_ULONG, BASE_TYPE_NONE }, - { "sfixed32", BASE_TYPE_INT, BASE_TYPE_NONE }, - { "sfixed64", BASE_TYPE_LONG, BASE_TYPE_NONE }, - { "bool", BASE_TYPE_BOOL, BASE_TYPE_NONE }, - { "string", BASE_TYPE_STRING, BASE_TYPE_NONE }, - { "bytes", BASE_TYPE_VECTOR, BASE_TYPE_UCHAR }, - { nullptr, BASE_TYPE_NONE, BASE_TYPE_NONE } - }; - for (auto tl = lookup; tl->proto_type; tl++) { - if (attribute_ == tl->proto_type) { - type->base_type = tl->fb_type; - type->element = tl->element; - NEXT(); - return NoError(); - } - } - if (Is('.')) NEXT(); // qualified names may start with a . ? - ECHECK(ParseTypeIdent(*type)); - return NoError(); -} - -CheckedError Parser::SkipAnyJsonValue() { - switch (token_) { - case '{': { - size_t fieldn_outer = 0; - return ParseTableDelimiters( - fieldn_outer, nullptr, - [&](const std::string &, size_t &fieldn, - const StructDef *) -> CheckedError { - ECHECK(Recurse([&]() { return SkipAnyJsonValue(); })); - fieldn++; - return NoError(); - }); - } - case '[': { - uoffset_t count = 0; - return ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError { - return Recurse([&]() { return SkipAnyJsonValue(); }); - }); - } - case kTokenStringConstant: - case kTokenIntegerConstant: - case kTokenFloatConstant: NEXT(); break; - default: - if (IsIdent("true") || IsIdent("false") || IsIdent("null")) { - NEXT(); - } else - return TokenError(); - } - return NoError(); -} - -CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) { - switch (token_) { - case '{': { - auto start = builder->StartMap(); - size_t fieldn_outer = 0; - auto err = - ParseTableDelimiters(fieldn_outer, nullptr, - [&](const std::string &name, size_t &fieldn, - const StructDef *) -> CheckedError { - builder->Key(name); - ECHECK(ParseFlexBufferValue(builder)); - fieldn++; - return NoError(); - }); - ECHECK(err); - builder->EndMap(start); - break; - } - case '[': { - auto start = builder->StartVector(); - uoffset_t count = 0; - ECHECK(ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError { - return ParseFlexBufferValue(builder); - })); - builder->EndVector(start, false, false); - break; - } - case kTokenStringConstant: - builder->String(attribute_); - EXPECT(kTokenStringConstant); - break; - case kTokenIntegerConstant: - builder->Int(StringToInt(attribute_.c_str())); - EXPECT(kTokenIntegerConstant); - break; - case kTokenFloatConstant: { - double d; - StringToNumber(attribute_.c_str(), &d); - builder->Double(d); - EXPECT(kTokenFloatConstant); - break; - } - default: - if (IsIdent("true")) { - builder->Bool(true); - NEXT(); - } else if (IsIdent("false")) { - builder->Bool(false); - NEXT(); - } else if (IsIdent("null")) { - builder->Null(); - NEXT(); - } else - return TokenError(); - } - return NoError(); -} - -bool Parser::ParseFlexBuffer(const char *source, const char *source_filename, - flexbuffers::Builder *builder) { - auto ok = !StartParseFile(source, source_filename).Check() && - !ParseFlexBufferValue(builder).Check(); - if (ok) builder->Finish(); - return ok; -} - -bool Parser::Parse(const char *source, const char **include_paths, - const char *source_filename) { - FLATBUFFERS_ASSERT(0 == recurse_protection_counter); - bool r; - - if (opts.use_flexbuffers) { - r = ParseFlexBuffer(source, source_filename, &flex_builder_); - } else { - r = !ParseRoot(source, include_paths, source_filename).Check(); - } - FLATBUFFERS_ASSERT(0 == recurse_protection_counter); - return r; -} - -CheckedError Parser::StartParseFile(const char *source, - const char *source_filename) { - file_being_parsed_ = source_filename ? source_filename : ""; - source_ = source; - ResetState(source_); - error_.clear(); - ECHECK(SkipByteOrderMark()); - NEXT(); - if (Is(kTokenEof)) return Error("input file is empty"); - return NoError(); -} - -CheckedError Parser::ParseRoot(const char *source, const char **include_paths, - const char *source_filename) { - ECHECK(DoParse(source, include_paths, source_filename, nullptr)); - - // Check that all types were defined. - for (auto it = structs_.vec.begin(); it != structs_.vec.end();) { - auto &struct_def = **it; - if (struct_def.predecl) { - if (opts.proto_mode) { - // Protos allow enums to be used before declaration, so check if that - // is the case here. - EnumDef *enum_def = nullptr; - for (size_t components = - struct_def.defined_namespace->components.size() + 1; - components && !enum_def; components--) { - auto qualified_name = - struct_def.defined_namespace->GetFullyQualifiedName( - struct_def.name, components - 1); - enum_def = LookupEnum(qualified_name); - } - if (enum_def) { - // This is pretty slow, but a simple solution for now. - auto initial_count = struct_def.refcount; - for (auto struct_it = structs_.vec.begin(); - struct_it != structs_.vec.end(); ++struct_it) { - auto &sd = **struct_it; - for (auto field_it = sd.fields.vec.begin(); - field_it != sd.fields.vec.end(); ++field_it) { - auto &field = **field_it; - if (field.value.type.struct_def == &struct_def) { - field.value.type.struct_def = nullptr; - field.value.type.enum_def = enum_def; - auto &bt = field.value.type.base_type == BASE_TYPE_VECTOR - ? field.value.type.element - : field.value.type.base_type; - FLATBUFFERS_ASSERT(bt == BASE_TYPE_STRUCT); - bt = enum_def->underlying_type.base_type; - struct_def.refcount--; - enum_def->refcount++; - } - } - } - if (struct_def.refcount) - return Error("internal: " + NumToString(struct_def.refcount) + "/" + - NumToString(initial_count) + - " use(s) of pre-declaration enum not accounted for: " + - enum_def->name); - structs_.dict.erase(structs_.dict.find(struct_def.name)); - it = structs_.vec.erase(it); - delete &struct_def; - continue; // Skip error. - } - } - auto err = "type referenced but not defined (check namespace): " + - struct_def.name; - if (struct_def.original_location) - err += ", originally at: " + *struct_def.original_location; - return Error(err); - } - ++it; - } - - // This check has to happen here and not earlier, because only now do we - // know for sure what the type of these are. - for (auto it = enums_.vec.begin(); it != enums_.vec.end(); ++it) { - auto &enum_def = **it; - if (enum_def.is_union) { - for (auto val_it = enum_def.Vals().begin(); - val_it != enum_def.Vals().end(); ++val_it) { - auto &val = **val_it; - if (!SupportsAdvancedUnionFeatures() && val.union_type.struct_def && - val.union_type.struct_def->fixed) - return Error( - "only tables can be union elements in the generated language: " + - val.name); - } - } - } - return NoError(); -} - -CheckedError Parser::DoParse(const char *source, const char **include_paths, - const char *source_filename, - const char *include_filename) { - if (source_filename) { - if (included_files_.find(source_filename) == included_files_.end()) { - included_files_[source_filename] = - include_filename ? include_filename : ""; - files_included_per_file_[source_filename] = std::set(); - } else { - return NoError(); - } - } - if (!include_paths) { - static const char *current_directory[] = { "", nullptr }; - include_paths = current_directory; - } - field_stack_.clear(); - builder_.Clear(); - // Start with a blank namespace just in case this file doesn't have one. - current_namespace_ = empty_namespace_; - - ECHECK(StartParseFile(source, source_filename)); - - // Includes must come before type declarations: - for (;;) { - // Parse pre-include proto statements if any: - if (opts.proto_mode && (attribute_ == "option" || attribute_ == "syntax" || - attribute_ == "package")) { - ECHECK(ParseProtoDecl()); - } else if (IsIdent("native_include")) { - NEXT(); - vector_emplace_back(&native_included_files_, attribute_); - EXPECT(kTokenStringConstant); - EXPECT(';'); - } else if (IsIdent("include") || (opts.proto_mode && IsIdent("import"))) { - NEXT(); - if (opts.proto_mode && attribute_ == "public") NEXT(); - auto name = flatbuffers::PosixPath(attribute_.c_str()); - EXPECT(kTokenStringConstant); - // Look for the file in include_paths. - std::string filepath; - for (auto paths = include_paths; paths && *paths; paths++) { - filepath = flatbuffers::ConCatPathFileName(*paths, name); - if (FileExists(filepath.c_str())) break; - } - if (filepath.empty()) - return Error("unable to locate include file: " + name); - if (source_filename) - files_included_per_file_[source_filename].insert(filepath); - if (included_files_.find(filepath) == included_files_.end()) { - // We found an include file that we have not parsed yet. - // Load it and parse it. - std::string contents; - if (!LoadFile(filepath.c_str(), true, &contents)) - return Error("unable to load include file: " + name); - ECHECK(DoParse(contents.c_str(), include_paths, filepath.c_str(), - name.c_str())); - // We generally do not want to output code for any included files: - if (!opts.generate_all) MarkGenerated(); - // Reset these just in case the included file had them, and the - // parent doesn't. - root_struct_def_ = nullptr; - file_identifier_.clear(); - file_extension_.clear(); - // This is the easiest way to continue this file after an include: - // instead of saving and restoring all the state, we simply start the - // file anew. This will cause it to encounter the same include - // statement again, but this time it will skip it, because it was - // entered into included_files_. - // This is recursive, but only go as deep as the number of include - // statements. - if (source_filename) { included_files_.erase(source_filename); } - return DoParse(source, include_paths, source_filename, - include_filename); - } - EXPECT(';'); - } else { - break; - } - } - // Now parse all other kinds of declarations: - while (token_ != kTokenEof) { - if (opts.proto_mode) { - ECHECK(ParseProtoDecl()); - } else if (IsIdent("namespace")) { - ECHECK(ParseNamespace()); - } else if (token_ == '{') { - if (!root_struct_def_) - return Error("no root type set to parse json with"); - if (builder_.GetSize()) { - return Error("cannot have more than one json object in a file"); - } - uoffset_t toff; - ECHECK(ParseTable(*root_struct_def_, nullptr, &toff)); - if (opts.size_prefixed) { - builder_.FinishSizePrefixed( - Offset
(toff), - file_identifier_.length() ? file_identifier_.c_str() : nullptr); - } else { - builder_.Finish(Offset
(toff), file_identifier_.length() - ? file_identifier_.c_str() - : nullptr); - } - // Check that JSON file doesn't contain more objects or IDL directives. - // Comments after JSON are allowed. - EXPECT(kTokenEof); - } else if (IsIdent("enum")) { - ECHECK(ParseEnum(false, nullptr)); - } else if (IsIdent("union")) { - ECHECK(ParseEnum(true, nullptr)); - } else if (IsIdent("root_type")) { - NEXT(); - auto root_type = attribute_; - EXPECT(kTokenIdentifier); - ECHECK(ParseNamespacing(&root_type, nullptr)); - if (opts.root_type.empty()) { - if (!SetRootType(root_type.c_str())) - return Error("unknown root type: " + root_type); - if (root_struct_def_->fixed) return Error("root type must be a table"); - } - EXPECT(';'); - } else if (IsIdent("file_identifier")) { - NEXT(); - file_identifier_ = attribute_; - EXPECT(kTokenStringConstant); - if (file_identifier_.length() != FlatBufferBuilder::kFileIdentifierLength) - return Error("file_identifier must be exactly " + - NumToString(FlatBufferBuilder::kFileIdentifierLength) + - " characters"); - EXPECT(';'); - } else if (IsIdent("file_extension")) { - NEXT(); - file_extension_ = attribute_; - EXPECT(kTokenStringConstant); - EXPECT(';'); - } else if (IsIdent("include")) { - return Error("includes must come before declarations"); - } else if (IsIdent("attribute")) { - NEXT(); - auto name = attribute_; - if (Is(kTokenIdentifier)) { - NEXT(); - } else { - EXPECT(kTokenStringConstant); - } - EXPECT(';'); - known_attributes_[name] = false; - } else if (IsIdent("rpc_service")) { - ECHECK(ParseService()); - } else { - ECHECK(ParseDecl()); - } - } - return NoError(); -} - -std::set Parser::GetIncludedFilesRecursive( - const std::string &file_name) const { - std::set included_files; - std::list to_process; - - if (file_name.empty()) return included_files; - to_process.push_back(file_name); - - while (!to_process.empty()) { - std::string current = to_process.front(); - to_process.pop_front(); - included_files.insert(current); - - // Workaround the lack of const accessor in C++98 maps. - auto &new_files = - (*const_cast> *>( - &files_included_per_file_))[current]; - for (auto it = new_files.begin(); it != new_files.end(); ++it) { - if (included_files.find(*it) == included_files.end()) - to_process.push_back(*it); - } - } - - return included_files; -} - -// Schema serialization functionality: - -template bool compareName(const T *a, const T *b) { - return a->defined_namespace->GetFullyQualifiedName(a->name) < - b->defined_namespace->GetFullyQualifiedName(b->name); -} - -template void AssignIndices(const std::vector &defvec) { - // Pre-sort these vectors, such that we can set the correct indices for them. - auto vec = defvec; - std::sort(vec.begin(), vec.end(), compareName); - for (int i = 0; i < static_cast(vec.size()); i++) vec[i]->index = i; -} - -void Parser::Serialize() { - builder_.Clear(); - AssignIndices(structs_.vec); - AssignIndices(enums_.vec); - std::vector> object_offsets; - for (auto it = structs_.vec.begin(); it != structs_.vec.end(); ++it) { - auto offset = (*it)->Serialize(&builder_, *this); - object_offsets.push_back(offset); - (*it)->serialized_location = offset.o; - } - std::vector> enum_offsets; - for (auto it = enums_.vec.begin(); it != enums_.vec.end(); ++it) { - auto offset = (*it)->Serialize(&builder_, *this); - enum_offsets.push_back(offset); - (*it)->serialized_location = offset.o; - } - std::vector> service_offsets; - for (auto it = services_.vec.begin(); it != services_.vec.end(); ++it) { - auto offset = (*it)->Serialize(&builder_, *this); - service_offsets.push_back(offset); - (*it)->serialized_location = offset.o; - } - auto objs__ = builder_.CreateVectorOfSortedTables(&object_offsets); - auto enum__ = builder_.CreateVectorOfSortedTables(&enum_offsets); - auto fiid__ = builder_.CreateString(file_identifier_); - auto fext__ = builder_.CreateString(file_extension_); - auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets); - auto schema_offset = reflection::CreateSchema( - builder_, objs__, enum__, fiid__, fext__, - (root_struct_def_ ? root_struct_def_->serialized_location : 0), serv__); - if (opts.size_prefixed) { - builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier()); - } else { - builder_.Finish(schema_offset, reflection::SchemaIdentifier()); - } -} - -static Namespace *GetNamespace( - const std::string &qualified_name, std::vector &namespaces, - std::map &namespaces_index) { - size_t dot = qualified_name.find_last_of('.'); - std::string namespace_name = (dot != std::string::npos) - ? std::string(qualified_name.c_str(), dot) - : ""; - Namespace *&ns = namespaces_index[namespace_name]; - - if (!ns) { - ns = new Namespace(); - namespaces.push_back(ns); - - size_t pos = 0; - - for (;;) { - dot = qualified_name.find('.', pos); - if (dot == std::string::npos) { break; } - ns->components.push_back(qualified_name.substr(pos, dot - pos)); - pos = dot + 1; - } - } - - return ns; -} - -Offset StructDef::Serialize(FlatBufferBuilder *builder, - const Parser &parser) const { - std::vector> field_offsets; - for (auto it = fields.vec.begin(); it != fields.vec.end(); ++it) { - field_offsets.push_back((*it)->Serialize( - builder, static_cast(it - fields.vec.begin()), parser)); - } - auto qualified_name = defined_namespace->GetFullyQualifiedName(name); - auto name__ = builder->CreateString(qualified_name); - auto flds__ = builder->CreateVectorOfSortedTables(&field_offsets); - auto attr__ = SerializeAttributes(builder, parser); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - return reflection::CreateObject(*builder, name__, flds__, fixed, - static_cast(minalign), - static_cast(bytesize), attr__, docs__); -} - -bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) { - if (!DeserializeAttributes(parser, object->attributes())) return false; - DeserializeDoc(doc_comment, object->documentation()); - name = parser.UnqualifiedName(object->name()->str()); - predecl = false; - sortbysize = attributes.Lookup("original_order") == nullptr && !fixed; - const auto &of = *(object->fields()); - auto indexes = std::vector(of.size()); - for (uoffset_t i = 0; i < of.size(); i++) indexes[of.Get(i)->id()] = i; - size_t tmp_struct_size = 0; - for (size_t i = 0; i < indexes.size(); i++) { - auto field = of.Get(indexes[i]); - auto field_def = new FieldDef(); - if (!field_def->Deserialize(parser, field) || - fields.Add(field_def->name, field_def)) { - delete field_def; - return false; - } - if (fixed) { - // Recompute padding since that's currently not serialized. - auto size = InlineSize(field_def->value.type); - auto next_field = - i + 1 < indexes.size() ? of.Get(indexes[i + 1]) : nullptr; - tmp_struct_size += size; - field_def->padding = - next_field ? (next_field->offset() - field_def->value.offset) - size - : PaddingBytes(tmp_struct_size, minalign); - tmp_struct_size += field_def->padding; - } - } - FLATBUFFERS_ASSERT(static_cast(tmp_struct_size) == object->bytesize()); - return true; -} - -Offset FieldDef::Serialize(FlatBufferBuilder *builder, - uint16_t id, - const Parser &parser) const { - auto name__ = builder->CreateString(name); - auto type__ = value.type.Serialize(builder); - auto attr__ = SerializeAttributes(builder, parser); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - double d; - StringToNumber(value.constant.c_str(), &d); - return reflection::CreateField( - *builder, name__, type__, id, value.offset, - // Is uint64>max(int64) tested? - IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0, - // result may be platform-dependent if underlying is float (not double) - IsFloat(value.type.base_type) ? d : 0.0, deprecated, required, key, - attr__, docs__); - // TODO: value.constant is almost always "0", we could save quite a bit of - // space by sharing it. Same for common values of value.type. -} - -bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) { - name = field->name()->str(); - defined_namespace = parser.current_namespace_; - if (!value.type.Deserialize(parser, field->type())) return false; - value.offset = field->offset(); - if (IsInteger(value.type.base_type)) { - value.constant = NumToString(field->default_integer()); - } else if (IsFloat(value.type.base_type)) { - value.constant = FloatToString(field->default_real(), 16); - } - deprecated = field->deprecated(); - required = field->required(); - key = field->key(); - if (!DeserializeAttributes(parser, field->attributes())) return false; - // TODO: this should probably be handled by a separate attribute - if (attributes.Lookup("flexbuffer")) { - flexbuffer = true; - parser.uses_flexbuffers_ = true; - if (value.type.base_type != BASE_TYPE_VECTOR || - value.type.element != BASE_TYPE_UCHAR) - return false; - } - if (auto nested = attributes.Lookup("nested_flatbuffer")) { - auto nested_qualified_name = - parser.current_namespace_->GetFullyQualifiedName(nested->constant); - nested_flatbuffer = parser.LookupStruct(nested_qualified_name); - if (!nested_flatbuffer) return false; - } - shared = attributes.Lookup("shared") != nullptr; - DeserializeDoc(doc_comment, field->documentation()); - return true; -} - -Offset RPCCall::Serialize(FlatBufferBuilder *builder, - const Parser &parser) const { - auto name__ = builder->CreateString(name); - auto attr__ = SerializeAttributes(builder, parser); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - return reflection::CreateRPCCall( - *builder, name__, request->serialized_location, - response->serialized_location, attr__, docs__); -} - -bool RPCCall::Deserialize(Parser &parser, const reflection::RPCCall *call) { - name = call->name()->str(); - if (!DeserializeAttributes(parser, call->attributes())) return false; - DeserializeDoc(doc_comment, call->documentation()); - request = parser.structs_.Lookup(call->request()->name()->str()); - response = parser.structs_.Lookup(call->response()->name()->str()); - if (!request || !response) { return false; } - return true; -} - -Offset ServiceDef::Serialize(FlatBufferBuilder *builder, - const Parser &parser) const { - std::vector> servicecall_offsets; - for (auto it = calls.vec.begin(); it != calls.vec.end(); ++it) { - servicecall_offsets.push_back((*it)->Serialize(builder, parser)); - } - auto qualified_name = defined_namespace->GetFullyQualifiedName(name); - auto name__ = builder->CreateString(qualified_name); - auto call__ = builder->CreateVector(servicecall_offsets); - auto attr__ = SerializeAttributes(builder, parser); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - return reflection::CreateService(*builder, name__, call__, attr__, docs__); -} - -bool ServiceDef::Deserialize(Parser &parser, - const reflection::Service *service) { - name = parser.UnqualifiedName(service->name()->str()); - if (service->calls()) { - for (uoffset_t i = 0; i < service->calls()->size(); ++i) { - auto call = new RPCCall(); - if (!call->Deserialize(parser, service->calls()->Get(i)) || - calls.Add(call->name, call)) { - delete call; - return false; - } - } - } - if (!DeserializeAttributes(parser, service->attributes())) return false; - DeserializeDoc(doc_comment, service->documentation()); - return true; -} - -Offset EnumDef::Serialize(FlatBufferBuilder *builder, - const Parser &parser) const { - std::vector> enumval_offsets; - for (auto it = vals.vec.begin(); it != vals.vec.end(); ++it) { - enumval_offsets.push_back((*it)->Serialize(builder, parser)); - } - auto qualified_name = defined_namespace->GetFullyQualifiedName(name); - auto name__ = builder->CreateString(qualified_name); - auto vals__ = builder->CreateVector(enumval_offsets); - auto type__ = underlying_type.Serialize(builder); - auto attr__ = SerializeAttributes(builder, parser); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - return reflection::CreateEnum(*builder, name__, vals__, is_union, type__, - attr__, docs__); -} - -bool EnumDef::Deserialize(Parser &parser, const reflection::Enum *_enum) { - name = parser.UnqualifiedName(_enum->name()->str()); - for (uoffset_t i = 0; i < _enum->values()->size(); ++i) { - auto val = new EnumVal(); - if (!val->Deserialize(parser, _enum->values()->Get(i)) || - vals.Add(val->name, val)) { - delete val; - return false; - } - } - is_union = _enum->is_union(); - if (!underlying_type.Deserialize(parser, _enum->underlying_type())) { - return false; - } - if (!DeserializeAttributes(parser, _enum->attributes())) return false; - DeserializeDoc(doc_comment, _enum->documentation()); - return true; -} - -Offset EnumVal::Serialize(FlatBufferBuilder *builder, - const Parser &parser) const { - auto name__ = builder->CreateString(name); - auto type__ = union_type.Serialize(builder); - auto docs__ = parser.opts.binary_schema_comments - ? builder->CreateVectorOfStrings(doc_comment) - : 0; - return reflection::CreateEnumVal( - *builder, name__, value, - union_type.struct_def ? union_type.struct_def->serialized_location : 0, - type__, docs__); -} - -bool EnumVal::Deserialize(const Parser &parser, - const reflection::EnumVal *val) { - name = val->name()->str(); - value = val->value(); - if (!union_type.Deserialize(parser, val->union_type())) return false; - DeserializeDoc(doc_comment, val->documentation()); - return true; -} - -Offset Type::Serialize(FlatBufferBuilder *builder) const { - return reflection::CreateType( - *builder, static_cast(base_type), - static_cast(element), - struct_def ? struct_def->index : (enum_def ? enum_def->index : -1), - fixed_length); -} - -bool Type::Deserialize(const Parser &parser, const reflection::Type *type) { - if (type == nullptr) return true; - base_type = static_cast(type->base_type()); - element = static_cast(type->element()); - fixed_length = type->fixed_length(); - if (type->index() >= 0) { - bool is_series = type->base_type() == reflection::Vector || - type->base_type() == reflection::Array; - if (type->base_type() == reflection::Obj || - (is_series && type->element() == reflection::Obj)) { - if (static_cast(type->index()) < parser.structs_.vec.size()) { - struct_def = parser.structs_.vec[type->index()]; - struct_def->refcount++; - } else { - return false; - } - } else { - if (static_cast(type->index()) < parser.enums_.vec.size()) { - enum_def = parser.enums_.vec[type->index()]; - } else { - return false; - } - } - } - return true; -} - -flatbuffers::Offset< - flatbuffers::Vector>> -Definition::SerializeAttributes(FlatBufferBuilder *builder, - const Parser &parser) const { - std::vector> attrs; - for (auto kv = attributes.dict.begin(); kv != attributes.dict.end(); ++kv) { - auto it = parser.known_attributes_.find(kv->first); - FLATBUFFERS_ASSERT(it != parser.known_attributes_.end()); - if (parser.opts.binary_schema_builtins || !it->second) { - auto key = builder->CreateString(kv->first); - auto val = builder->CreateString(kv->second->constant); - attrs.push_back(reflection::CreateKeyValue(*builder, key, val)); - } - } - if (attrs.size()) { - return builder->CreateVectorOfSortedTables(&attrs); - } else { - return 0; - } -} - -bool Definition::DeserializeAttributes( - Parser &parser, const Vector> *attrs) { - if (attrs == nullptr) return true; - for (uoffset_t i = 0; i < attrs->size(); ++i) { - auto kv = attrs->Get(i); - auto value = new Value(); - if (kv->value()) { value->constant = kv->value()->str(); } - if (attributes.Add(kv->key()->str(), value)) { - delete value; - return false; - } - parser.known_attributes_[kv->key()->str()]; - } - return true; -} - -/************************************************************************/ -/* DESERIALIZATION */ -/************************************************************************/ -bool Parser::Deserialize(const uint8_t *buf, const size_t size) { - flatbuffers::Verifier verifier(reinterpret_cast(buf), size); - bool size_prefixed = false; - if (!reflection::SchemaBufferHasIdentifier(buf)) { - if (!flatbuffers::BufferHasIdentifier(buf, reflection::SchemaIdentifier(), - true)) - return false; - else - size_prefixed = true; - } - auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer - : &reflection::VerifySchemaBuffer; - if (!verify_fn(verifier)) { return false; } - auto schema = size_prefixed ? reflection::GetSizePrefixedSchema(buf) - : reflection::GetSchema(buf); - return Deserialize(schema); -} - -bool Parser::Deserialize(const reflection::Schema *schema) { - file_identifier_ = schema->file_ident() ? schema->file_ident()->str() : ""; - file_extension_ = schema->file_ext() ? schema->file_ext()->str() : ""; - std::map namespaces_index; - - // Create defs without deserializing so references from fields to structs and - // enums can be resolved. - for (auto it = schema->objects()->begin(); it != schema->objects()->end(); - ++it) { - auto struct_def = new StructDef(); - struct_def->bytesize = it->bytesize(); - struct_def->fixed = it->is_struct(); - struct_def->minalign = it->minalign(); - if (structs_.Add(it->name()->str(), struct_def)) { - delete struct_def; - return false; - } - auto type = new Type(BASE_TYPE_STRUCT, struct_def, nullptr); - if (types_.Add(it->name()->str(), type)) { - delete type; - return false; - } - } - for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) { - auto enum_def = new EnumDef(); - if (enums_.Add(it->name()->str(), enum_def)) { - delete enum_def; - return false; - } - auto type = new Type(BASE_TYPE_UNION, nullptr, enum_def); - if (types_.Add(it->name()->str(), type)) { - delete type; - return false; - } - } - - // Now fields can refer to structs and enums by index. - for (auto it = schema->objects()->begin(); it != schema->objects()->end(); - ++it) { - std::string qualified_name = it->name()->str(); - auto struct_def = structs_.Lookup(qualified_name); - struct_def->defined_namespace = - GetNamespace(qualified_name, namespaces_, namespaces_index); - if (!struct_def->Deserialize(*this, *it)) { return false; } - if (schema->root_table() == *it) { root_struct_def_ = struct_def; } - } - for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) { - std::string qualified_name = it->name()->str(); - auto enum_def = enums_.Lookup(qualified_name); - enum_def->defined_namespace = - GetNamespace(qualified_name, namespaces_, namespaces_index); - if (!enum_def->Deserialize(*this, *it)) { return false; } - } - - if (schema->services()) { - for (auto it = schema->services()->begin(); it != schema->services()->end(); - ++it) { - std::string qualified_name = it->name()->str(); - auto service_def = new ServiceDef(); - service_def->defined_namespace = - GetNamespace(qualified_name, namespaces_, namespaces_index); - if (!service_def->Deserialize(*this, *it) || - services_.Add(qualified_name, service_def)) { - delete service_def; - return false; - } - } - } - - return true; -} - -std::string Parser::ConformTo(const Parser &base) { - for (auto sit = structs_.vec.begin(); sit != structs_.vec.end(); ++sit) { - auto &struct_def = **sit; - auto qualified_name = - struct_def.defined_namespace->GetFullyQualifiedName(struct_def.name); - auto struct_def_base = base.LookupStruct(qualified_name); - if (!struct_def_base) continue; - for (auto fit = struct_def.fields.vec.begin(); - fit != struct_def.fields.vec.end(); ++fit) { - auto &field = **fit; - auto field_base = struct_def_base->fields.Lookup(field.name); - if (field_base) { - if (field.value.offset != field_base->value.offset) - return "offsets differ for field: " + field.name; - if (field.value.constant != field_base->value.constant) - return "defaults differ for field: " + field.name; - if (!EqualByName(field.value.type, field_base->value.type)) - return "types differ for field: " + field.name; - } else { - // Doesn't have to exist, deleting fields is fine. - // But we should check if there is a field that has the same offset - // but is incompatible (in the case of field renaming). - for (auto fbit = struct_def_base->fields.vec.begin(); - fbit != struct_def_base->fields.vec.end(); ++fbit) { - field_base = *fbit; - if (field.value.offset == field_base->value.offset) { - if (!EqualByName(field.value.type, field_base->value.type)) - return "field renamed to different type: " + field.name; - break; - } - } - } - } - } - for (auto eit = enums_.vec.begin(); eit != enums_.vec.end(); ++eit) { - auto &enum_def = **eit; - auto qualified_name = - enum_def.defined_namespace->GetFullyQualifiedName(enum_def.name); - auto enum_def_base = base.enums_.Lookup(qualified_name); - if (!enum_def_base) continue; - for (auto evit = enum_def.Vals().begin(); evit != enum_def.Vals().end(); - ++evit) { - auto &enum_val = **evit; - auto enum_val_base = enum_def_base->Lookup(enum_val.name); - if (enum_val_base) { - if (enum_val != *enum_val_base) - return "values differ for enum: " + enum_val.name; - } - } - } - return ""; -} - -} // namespace flatbuffers diff --git a/daemon/src/External/src/flatbuffers/util.cpp b/daemon/src/External/src/flatbuffers/util.cpp deleted file mode 100644 index 2eda1804..00000000 --- a/daemon/src/External/src/flatbuffers/util.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright 2016 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// clang-format off -// Dont't remove `format off`, it prevent reordering of win-includes. - -# define _POSIX_C_SOURCE 200809L -# define _XOPEN_SOURCE 700L - -#ifdef _WIN32 -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# ifndef NOMINMAX -# define NOMINMAX -# endif -# ifdef _MSC_VER -# include -# endif -# include // Must be included before -# include -# include -# undef interface // This is also important because of reasons -#endif -// clang-format on - -#include "flatbuffers/base.h" -#include "flatbuffers/util.h" - -#include -#include -#include -#include - -namespace flatbuffers { - -bool FileExistsRaw(const char *name) { - std::ifstream ifs(name); - return ifs.good(); -} - -bool LoadFileRaw(const char *name, bool binary, std::string *buf) { - if (DirExists(name)) return false; - std::ifstream ifs(name, binary ? std::ifstream::binary : std::ifstream::in); - if (!ifs.is_open()) return false; - if (binary) { - // The fastest way to read a file into a string. - ifs.seekg(0, std::ios::end); - auto size = ifs.tellg(); - (*buf).resize(static_cast(size)); - ifs.seekg(0, std::ios::beg); - ifs.read(&(*buf)[0], (*buf).size()); - } else { - // This is slower, but works correctly on all platforms for text files. - std::ostringstream oss; - oss << ifs.rdbuf(); - *buf = oss.str(); - } - return !ifs.bad(); -} - -static LoadFileFunction g_load_file_function = LoadFileRaw; -static FileExistsFunction g_file_exists_function = FileExistsRaw; - -bool LoadFile(const char *name, bool binary, std::string *buf) { - FLATBUFFERS_ASSERT(g_load_file_function); - return g_load_file_function(name, binary, buf); -} - -bool FileExists(const char *name) { - FLATBUFFERS_ASSERT(g_file_exists_function); - return g_file_exists_function(name); -} - -bool DirExists(const char *name) { - // clang-format off - - #ifdef _WIN32 - #define flatbuffers_stat _stat - #define FLATBUFFERS_S_IFDIR _S_IFDIR - #else - #define flatbuffers_stat stat - #define FLATBUFFERS_S_IFDIR S_IFDIR - #endif - // clang-format on - struct flatbuffers_stat file_info; - if (flatbuffers_stat(name, &file_info) != 0) return false; - return (file_info.st_mode & FLATBUFFERS_S_IFDIR) != 0; -} - -LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function) { - LoadFileFunction previous_function = g_load_file_function; - g_load_file_function = load_file_function ? load_file_function : LoadFileRaw; - return previous_function; -} - -FileExistsFunction SetFileExistsFunction( - FileExistsFunction file_exists_function) { - FileExistsFunction previous_function = g_file_exists_function; - g_file_exists_function = - file_exists_function ? file_exists_function : FileExistsRaw; - return previous_function; -} - -bool SaveFile(const char *name, const char *buf, size_t len, bool binary) { - std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out); - if (!ofs.is_open()) return false; - ofs.write(buf, len); - return !ofs.bad(); -} - -// We internally store paths in posix format ('/'). Paths supplied -// by the user should go through PosixPath to ensure correct behavior -// on Windows when paths are string-compared. - -static const char kPathSeparatorWindows = '\\'; -static const char *PathSeparatorSet = "\\/"; // Intentionally no ':' - -std::string StripExtension(const std::string &filepath) { - size_t i = filepath.find_last_of('.'); - return i != std::string::npos ? filepath.substr(0, i) : filepath; -} - -std::string GetExtension(const std::string &filepath) { - size_t i = filepath.find_last_of('.'); - return i != std::string::npos ? filepath.substr(i + 1) : ""; -} - -std::string StripPath(const std::string &filepath) { - size_t i = filepath.find_last_of(PathSeparatorSet); - return i != std::string::npos ? filepath.substr(i + 1) : filepath; -} - -std::string StripFileName(const std::string &filepath) { - size_t i = filepath.find_last_of(PathSeparatorSet); - return i != std::string::npos ? filepath.substr(0, i) : ""; -} - -std::string ConCatPathFileName(const std::string &path, - const std::string &filename) { - std::string filepath = path; - if (filepath.length()) { - char &filepath_last_character = string_back(filepath); - if (filepath_last_character == kPathSeparatorWindows) { - filepath_last_character = kPathSeparator; - } else if (filepath_last_character != kPathSeparator) { - filepath += kPathSeparator; - } - } - filepath += filename; - // Ignore './' at the start of filepath. - if (filepath[0] == '.' && filepath[1] == kPathSeparator) { - filepath.erase(0, 2); - } - return filepath; -} - -std::string PosixPath(const char *path) { - std::string p = path; - std::replace(p.begin(), p.end(), '\\', '/'); - return p; -} - -void EnsureDirExists(const std::string &filepath) { - auto parent = StripFileName(filepath); - if (parent.length()) EnsureDirExists(parent); - // clang-format off - - #ifdef _WIN32 - (void)_mkdir(filepath.c_str()); - #else - mkdir(filepath.c_str(), S_IRWXU|S_IRGRP|S_IXGRP); - #endif - // clang-format on -} - -std::string AbsolutePath(const std::string &filepath) { - // clang-format off - - #ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION - return filepath; - #else - #ifdef _WIN32 - char abs_path[MAX_PATH]; - return GetFullPathNameA(filepath.c_str(), MAX_PATH, abs_path, nullptr) - #else - char *abs_path_temp = realpath(filepath.c_str(), nullptr); - bool success = abs_path_temp != nullptr; - std::string abs_path; - if(success) { - abs_path = abs_path_temp; - free(abs_path_temp); - } - return success - #endif - ? abs_path - : filepath; - #endif // FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION - // clang-format on -} - -// Locale-independent code. -#if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && \ - (FLATBUFFERS_LOCALE_INDEPENDENT > 0) - -// clang-format off -// Allocate locale instance at startup of application. -ClassicLocale ClassicLocale::instance_; - -#ifdef _MSC_VER - ClassicLocale::ClassicLocale() - : locale_(_create_locale(LC_ALL, "C")) {} - ClassicLocale::~ClassicLocale() { _free_locale(locale_); } -#else - ClassicLocale::ClassicLocale() - : locale_(newlocale(LC_ALL, "C", nullptr)) {} - ClassicLocale::~ClassicLocale() { freelocale(locale_); } -#endif -// clang-format on - -#endif // !FLATBUFFERS_LOCALE_INDEPENDENT - -std::string RemoveStringQuotes(const std::string &s) { - auto ch = *s.c_str(); - return ((s.size() >= 2) && (ch == '\"' || ch == '\'') && - (ch == string_back(s))) - ? s.substr(1, s.length() - 2) - : s; -} - -bool SetGlobalTestLocale(const char *locale_name, std::string *_value) { - const auto the_locale = setlocale(LC_ALL, locale_name); - if (!the_locale) return false; - if (_value) *_value = std::string(the_locale); - return true; -} - -bool ReadEnvironmentVariable(const char *var_name, std::string *_value) { -#ifdef _MSC_VER - __pragma(warning(disable : 4996)); // _CRT_SECURE_NO_WARNINGS -#endif - auto env_str = std::getenv(var_name); - if (!env_str) return false; - if (_value) *_value = std::string(env_str); - return true; -} - -void SetupDefaultCRTReportMode() { - // clang-format off - - #ifdef _MSC_VER - // By default, send all reports to STDOUT to prevent CI hangs. - // Enable assert report box [Abort|Retry|Ignore] if a debugger is present. - const int dbg_mode = (_CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG) | - (IsDebuggerPresent() ? _CRTDBG_MODE_WNDW : 0); - (void)dbg_mode; // release mode fix - // CrtDebug reports to _CRT_WARN channel. - _CrtSetReportMode(_CRT_WARN, dbg_mode); - _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); - // The assert from reports to _CRT_ERROR channel - _CrtSetReportMode(_CRT_ERROR, dbg_mode); - _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT); - // Internal CRT assert channel? - _CrtSetReportMode(_CRT_ASSERT, dbg_mode); - _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); - #endif - - // clang-format on -} - -} // namespace flatbuffers diff --git a/daemon/src/Rpc/Connection.cpp b/daemon/src/Rpc/Connection.cpp deleted file mode 100644 index 0c584b4f..00000000 --- a/daemon/src/Rpc/Connection.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include "Connection.hpp" - -#include -#include - -#include -#include -#include - -#include - -extern "C" -{ - #include - #include -}; - -using namespace Mira::Rpc; - -Connection::Connection(Rpc::Server* p_Server, uint32_t p_ClientId, int32_t p_Socket, struct sockaddr_in& p_Address) : - m_Socket(p_Socket), - m_ClientId(p_ClientId), - m_Running(false), - m_Thread(-1), - m_Address { 0 }, - m_Server(p_Server) -{ - memcpy(&m_Address, &p_Address, sizeof(m_Address)); -} - -Connection::~Connection() -{ - auto s_Ret = 0; - - // Close the socket - do - { - if (m_Socket == -1) - break; - - s_Ret = shutdown(m_Socket, SHUT_RDWR); - if (s_Ret != 0) - { - fprintf(stderr, "err: could not shutdown socket (%d).\n", s_Ret); - break; - } - - s_Ret = close(m_Socket); - if (s_Ret != 0) - { - fprintf(stderr, "err: could not close socket (%d).\n", s_Ret); - break; - } - } while (false); - - - // Cancel the thread if needed - do - { - void* s_RetVal = nullptr; - - // Check the thread - if (m_Thread == -1) - break; - - // Cancel the thread - s_Ret = scePthreadCancel(m_Thread); - if (s_Ret != 0) - { - fprintf(stderr, "err: cancel connection thread returned (%d).\n", s_Ret); - break; - } - - // Wait for the thread to exit - s_Ret = scePthreadJoin(m_Thread, &s_RetVal); - if (s_Ret != 0) - { - fprintf(stderr, "err: could not join thread (%lu) ret (%d).\n", m_Thread, s_Ret); - break; - } - } while (false); -} - -void Connection::Disconnect() -{ - m_Running = false; -} - -void* Connection::ConnectionThread(void* p_ConnectionInstance) -{ - auto s_Connection = static_cast(p_ConnectionInstance); - if (s_Connection == nullptr) - return nullptr; - - auto s_Socket = s_Connection->GetSocket(); - if (s_Socket < 0) - return nullptr; - - uint64_t s_IncomingMessageSize = 0; - ssize_t s_Ret = -1; - - while ((s_Ret = recv(s_Socket, &s_IncomingMessageSize, sizeof(s_IncomingMessageSize), 0)) > 0 && s_Connection->IsRunning()) - { - if (s_Ret != sizeof(s_IncomingMessageSize)) - { - fprintf(stderr, "err: could not get message size.\n"); - break; - } - - if (s_IncomingMessageSize > RpcConnection_MaxMessageSize) - { - fprintf(stderr, "err: incoming message size (0x%lx) > max (0x%x).\n", s_IncomingMessageSize, RpcConnection_MaxMessageSize); - break; - } - - if (s_IncomingMessageSize == 0) - { - fprintf(stderr, "err: invalid incoming message size of 0.\n"); - break; - } - - // Allocate the new data - std::vector s_Data; - s_Data.reserve(s_IncomingMessageSize); - - // Read in all of the data from the socket - s_Ret = recv(s_Socket, s_Data.data(), s_IncomingMessageSize, 0); - if (s_Ret != s_IncomingMessageSize) - { - fprintf(stderr, "err: wanted data (0x%zx) != (0x%lx).\n", s_Ret, s_IncomingMessageSize); - break; - } - - // Create a new verifier - auto s_Verifier = flatbuffers::Verifier(s_Data.data(), s_IncomingMessageSize); - - // Validate the header - auto s_Valid = VerifyRpcHeaderBuffer(s_Verifier); - if (!s_Valid) - { - fprintf(stderr, "err: could not verify flatbuffer.\n"); - break; - } - - // Get the header - auto s_Header = GetRpcHeader(s_Data.data()); - if (s_Header == nullptr) - { - fprintf(stderr, "err: header invalid.\n"); - break; - } - - // Validate the header magic - if (s_Header->magic() != RpcMagics_Version2) - { - fprintf(stderr, "err: invalid magic (%d) wanted (%d).\n", s_Header->magic(), RpcMagics_Version2); - break; - } - - // Validate the category - if (s_Header->category() < RpcCategory_NONE || s_Header->category() >= RpcCategory_MAX) - { - fprintf(stderr, "err: invalid category (%d).\n", s_Header->category()); - break; - } - - auto s_MessageManager = Daemon::GetInstance()->GetMessageManager(); - if (s_MessageManager == nullptr) - { - fprintf(stderr, "err: no message manager.\n"); - break; - } - - s_MessageManager->OnRequest(s_Connection, s_Header); - } - - return nullptr; -} \ No newline at end of file diff --git a/daemon/src/Rpc/Connection.hpp b/daemon/src/Rpc/Connection.hpp index 4f1f235b..6bbb08ca 100644 --- a/daemon/src/Rpc/Connection.hpp +++ b/daemon/src/Rpc/Connection.hpp @@ -1,63 +1,38 @@ #pragma once -#include -#include +#include extern "C" { #include -}; - -#include +} namespace Mira { namespace Rpc { - class Server; - class Connection { private: - enum - { - RpcConnection_MaxMessageSize = 0x400000, - }; - - // Client socket + uint64_t m_Id; int32_t m_Socket; - - // Client id - uint32_t m_ClientId; - - // Is the client connection still running - volatile bool m_Running; - - // Thread - OrbisPthread m_Thread; - - // Client address struct sockaddr_in m_Address; - // Reference to the server class - Rpc::Server* m_Server; - - // TODO: mutex + std::function OnDisconnectCallback; public: - Connection(Rpc::Server* p_Server, uint32_t p_ClientId, int32_t p_Socket, struct sockaddr_in& p_Address); - ~Connection(); - - void Disconnect(); + Connection(uint64_t p_Id, int32_t p_Socket, struct sockaddr_in& p_Address, std::function p_DisconnectCallback) : + m_Id(p_Id), + m_Socket(p_Socket), + m_Address { 0 }, + OnDisconnectCallback(p_DisconnectCallback) + { + // Copy over our client address + memcpy(&m_Address, &p_Address, sizeof(m_Address)); + } + uint64_t GetId() const { return m_Id; } int32_t GetSocket() const { return m_Socket; } - uint32_t GetId() const { return m_ClientId; } - bool IsRunning() const { return m_Running; } - - struct sockaddr_in& GetAddress() { return m_Address; } - - OrbisPthread* GetThreadPointer() { return &m_Thread; } - - static void* ConnectionThread(void* p_ConnectionInstance); + const struct sockaddr_in& GetAddress() const { return m_Address; } }; } } \ No newline at end of file diff --git a/daemon/src/Rpc/FileManagerListener.cpp b/daemon/src/Rpc/FileManagerListener.cpp new file mode 100644 index 00000000..544867c5 --- /dev/null +++ b/daemon/src/Rpc/FileManagerListener.cpp @@ -0,0 +1,357 @@ +#if 0 + +#include "FileManagerListener.hpp" +#include "Protos/FileManager.pb.h" + +extern "C" +{ + #include + #include + #include +} +using namespace Mira::Rpc; + +#ifdef _PROTOBUF +FileManagerListener::FileManagerListener(google::protobuf::Arena* p_Arena) : + Listener(p_Arena) +#else +FileManagerListener::FileManagerListener() +#endif +{ + +} + +FileManagerListener::~FileManagerListener() +{ + +} + +Status FileManagerListener::OnMessage(RpcMessage* p_Request, RpcMessage* p_Response) +{ +#ifdef _PROTOBUF + if (p_Request->inner_message().Is()) + return OnEcho(p_Request, p_Response); + + if (p_Request->inner_message().Is()) + return OnOpen(p_Request, p_Response); + + if (p_Request->inner_message().Is()) + return OnClose(p_Request, p_Response); + + if (p_Request->inner_message().Is()) + return OnRead(p_Request, p_Response); + + if (p_Request->inner_message().Is()) + return OnList(p_Request, p_Response); + + if (p_Request->inner_message().Is()) + return OnStat(p_Request, p_Response); + + if (p_Request->inner_message().Is()) + return OnMkdir(p_Request, p_Response); + + if (p_Request->inner_message().Is()) + return OnUnlink(p_Request, p_Response); + + + // By default if we don't have the message we are looking for report that we skipped + // This will ensure that the manager calls the next listener + return Status::SKIPPED; +#else + return (Status)0; +#endif +} + +Status FileManagerListener::OnEcho(RpcMessage* p_Request, RpcMessage* p_Response) +{ + // Parse the incoming message + FileManager::EchoRequest s_Request; + if (!p_Request->inner_message().UnpackTo(&s_Request)) + { + WriteLog(LL_Error, "could not parse echo request."); + return Status::CANCELLED; + } + + WriteLog(LL_Info, "[Echo]: %s", s_Request.message().c_str()); + + // Clear the error on the response + p_Response->set_error(0); + + return Status::OK; +} + +Status FileManagerListener::OnOpen(RpcMessage* p_Request, RpcMessage* p_Response) +{ + FileManager::OpenRequest s_Request; + if (!p_Request->inner_message().UnpackTo(&s_Request)) + { + WriteLog(LL_Error, "could not parse open request."); + return Status::CANCELLED; + } + + WriteLog(LL_Debug, "open request p:(%s) m:(%d) f:(%d).", s_Request.path().c_str(), s_Request.mode(), s_Request.flags()); + + auto s_Ret = open(s_Request.path().c_str(), s_Request.flags(), s_Request.mode()); + if (s_Ret == -1) + { + p_Response->set_error(errno); + WriteLog(LL_Error, "could not open file err: (%d).", errno); + return Status::OK; + } + + FileManager::OpenResponse s_OpenResponse; + s_OpenResponse.set_fd(s_Ret); + + SetInnerMessage(p_Response, s_OpenResponse); + + // Clear the error + p_Response->set_error(0); + + return Status::OK; +} + +Status FileManagerListener::OnClose(RpcMessage* p_Request, RpcMessage* p_Response) +{ + // Unserialize the incoming request + FileManager::CloseRequest s_Request; + if (!p_Request->inner_message().UnpackTo(&s_Request)) + { + WriteLog(LL_Error, "could not parse close request."); + return Status::CANCELLED; + } + + // Debug logging + WriteLog(LL_Debug, "close request: fd: (%d).", s_Request.handle()); + + // Close the specified handle + auto s_Ret = close(s_Request.handle()); + if (s_Ret == -1) + { + WriteLog(LL_Error, "could not close handle (%d), err: (%d).", s_Request.handle(), errno); + p_Response->set_error(errno); + return Status::OK; + } + + p_Response->set_error(0); + return Status::OK; +} + +Status FileManagerListener::OnRead(RpcMessage* p_Request, RpcMessage* p_Response) +{ + FileManager::ReadRequest s_ReadRequest; + if (!p_Request->inner_message().UnpackTo(&s_ReadRequest)) + { + WriteLog(LL_Error, "could not parse read request."); + return Status::CANCELLED; + } + + // Debug logging + WriteLog(LL_Debug, "read request: fd: (%d), size: (%lx).", s_ReadRequest.handle(), s_ReadRequest.size()); + + // Validate max size + if (s_ReadRequest.size() > MaxBufferSize) + { + WriteLog(LL_Error, "requested size (%lx) > max size (%lx).", s_ReadRequest.size(), MaxBufferSize); + p_Response->set_error(EMSGSIZE); + return Status::OK; + } + + // Create a buffer to hold our data + std::string s_Buffer; + s_Buffer.resize(s_ReadRequest.size()); + + // Read the data out + auto s_Ret = read(s_ReadRequest.handle(), (void*)s_Buffer.data(), s_ReadRequest.size()); + if (s_Ret == -1) + { + WriteLog(LL_Error, "could not read (%lx) from fd: (%d), err: (%d).", s_ReadRequest.size(), s_ReadRequest.handle(), errno); + p_Response->set_error(errno); + return Status::OK; + } + + // Read from specified handle + FileManager::ReadResponse s_ReadResponse; + s_ReadResponse.set_data(s_Buffer); + + SetInnerMessage(p_Response, s_ReadResponse); + p_Response->set_error(0); + + return Status::OK; +} + +Status FileManagerListener::OnList(RpcMessage* p_Request, RpcMessage* p_Response) +{ + FileManager::ListRequest s_ListRequest; + if (!p_Request->inner_message().UnpackTo(&s_ListRequest)) + { + WriteLog(LL_Error, "could not parse list request."); + return Status::CANCELLED; + } + + // Attempt to open the directory + auto s_Directory = opendir(s_ListRequest.path().c_str()); + if (s_Directory == nullptr) + { + WriteLog(LL_Error, "could not open directory (%s), err: (%d).", s_ListRequest.path().c_str(), errno); + p_Response->set_error(errno); + return Status::OK; + } + + FileManager::ListResponse s_ListResponse; + auto s_Entries = s_ListResponse.mutable_entries(); + + struct dirent* s_DirEnt = nullptr; + while ((s_DirEnt = readdir(s_Directory))) + { + auto l_Entry = s_Entries->Add(); + l_Entry->set_name(s_DirEnt->d_name); + // l_Entry->set_inode(s_DirEnt->d_ino); + // l_Entry->set_offset(s_DirEnt->d_off); + + switch (s_DirEnt->d_type) + { + case DT_BLK: + l_Entry->set_type(FileManager::ListTypes::BLOCK_DEVICE); + break; + case DT_CHR: + l_Entry->set_type(FileManager::ListTypes::CHARACTER_DEVICE); + break; + case DT_DIR: + l_Entry->set_type(FileManager::ListTypes::DIRECTORY); + break; + case DT_FIFO: + l_Entry->set_type(FileManager::ListTypes::NAMED_PIPE); + break; + default: + l_Entry->set_type(FileManager::ListTypes::UNKNOWN); + }; + + } + + auto s_Ret = closedir(s_Directory); + if (s_Ret == -1) + { + WriteLog(LL_Error, "could not close directory err: (%d).", errno); + p_Response->set_error(0); + return Status::OK; + } + + p_Response->set_error(0); + SetInnerMessage(p_Response, s_ListResponse); + + return Status::OK; +} + +Status FileManagerListener::OnStat(RpcMessage* p_Request, RpcMessage* p_Response) +{ + FileManager::StatRequest s_StatRequest; + if (!p_Request->inner_message().UnpackTo(&s_StatRequest)) + { + WriteLog(LL_Error, "could not parse stat request."); + return Status::CANCELLED; + } + + struct stat s_Stat = { 0 }; + auto s_Ret = stat(s_StatRequest.path().c_str(), &s_Stat); + if (s_Ret == -1) + { + WriteLog(LL_Error, "could not stat (%s), err: (%d).", s_StatRequest.path().c_str(), errno); + p_Response->set_error(errno); + return Status::OK; + } + + FileManager::StatResponse s_StatResponse; + s_StatResponse.set_device(s_Stat.st_dev); + s_StatResponse.set_inode(s_Stat.st_ino); + s_StatResponse.set_protection(s_Stat.st_mode); + s_StatResponse.set_num_hard_links(s_Stat.st_nlink); + s_StatResponse.set_user_id(s_Stat.st_uid); + s_StatResponse.set_group_id(s_Stat.st_gid); + s_StatResponse.set_device_id(s_Stat.st_rdev); + s_StatResponse.set_size(s_Stat.st_size); + s_StatResponse.set_block_size(s_Stat.st_blksize); + s_StatResponse.set_blocks(s_Stat.st_blocks); + + auto s_AccessTime = google::protobuf::Arena::CreateMessage(m_Arena); + if (s_AccessTime == nullptr) + { + WriteLog(LL_Error, "could not allocate access time."); + p_Response->set_error(ENOMEM); + return Status::OK; + } + s_AccessTime->set_seconds(s_Stat.st_atim.tv_sec); + s_AccessTime->set_nanoseconds(s_Stat.st_atim.tv_nsec); + s_StatResponse.set_allocated_access_time(s_AccessTime); + + auto s_ModTime = google::protobuf::Arena::CreateMessage(m_Arena); + if (s_ModTime == nullptr) + { + WriteLog(LL_Error, "could not allocate mod time."); + p_Response->set_error(ENOMEM); + return Status::OK; + } + s_ModTime->set_seconds(s_Stat.st_mtim.tv_sec); + s_ModTime->set_nanoseconds(s_Stat.st_mtim.tv_nsec); + s_StatResponse.set_allocated_mod_time(s_ModTime); + + auto s_StatusTime = google::protobuf::Arena::CreateMessage(m_Arena); + if (s_StatusTime == nullptr) + { + WriteLog(LL_Error, "could not allocate status time."); + p_Response->set_error(ENOMEM); + return Status::OK; + } + s_StatusTime->set_seconds(s_Stat.st_ctim.tv_sec); + s_StatusTime->set_nanoseconds(s_Stat.st_ctim.tv_nsec); + s_StatResponse.set_allocated_status_time(s_StatusTime); + + SetInnerMessage(p_Response, s_StatResponse); + p_Response->set_error(0); + + return Status::OK; +} + +Status FileManagerListener::OnMkdir(RpcMessage* p_Request, RpcMessage* p_Response) +{ + FileManager::MkdirRequest s_Request; + if (!p_Request->inner_message().UnpackTo(&s_Request)) + { + WriteLog(LL_Error, "could not parse mkdir request."); + return Status::CANCELLED; + } + + auto s_Ret = mkdir(s_Request.path().c_str(), s_Request.mode()); + if (s_Ret == -1) + { + WriteLog(LL_Error, "could not mkdir (%s), err: (%d).", s_Request.path().c_str(), errno); + p_Response->set_error(errno); + return Status::OK; + } + + p_Response->set_error(0); + + return Status::OK; +} + +Status FileManagerListener::OnUnlink(RpcMessage* p_Request, RpcMessage* p_Response) +{ + FileManager::UnlinkRequest s_UnlinkRequest; + if (!p_Request->inner_message().UnpackTo(&s_UnlinkRequest)) + { + WriteLog(LL_Error, "could not parse unlink request."); + return Status::CANCELLED; + } + + auto s_Ret = unlink(s_UnlinkRequest.path().c_str()); + if (s_Ret == -1) + { + WriteLog(LL_Error, "could not unlink (%s), err: (%d).", s_UnlinkRequest.path().c_str(), errno); + p_Response->set_error(errno); + return Status::OK; + } + + p_Response->set_error(0); + + return Status::OK; +} +#endif \ No newline at end of file diff --git a/daemon/src/Rpc/FileManagerListener.hpp b/daemon/src/Rpc/FileManagerListener.hpp new file mode 100644 index 00000000..62785e83 --- /dev/null +++ b/daemon/src/Rpc/FileManagerListener.hpp @@ -0,0 +1,36 @@ +#pragma once +#include "Listener.hpp" + +namespace Mira +{ + namespace Rpc + { + class FileManagerListener : + public Listener + { + private: + enum + { + MaxBufferSize = 0xFFFF + }; + + public: + #ifdef _PROTOBUF + FileManagerListener(google::protobuf::Arena* p_Arena); + #else + FileManagerListener(); + #endif + virtual ~FileManagerListener(); + virtual Status OnMessage(RpcMessage* p_Request, RpcMessage* p_Response) override; + + Status OnEcho(RpcMessage* p_Request, RpcMessage* p_Response); + Status OnOpen(RpcMessage* p_Request, RpcMessage* p_Response); + Status OnClose(RpcMessage* p_Request, RpcMessage* p_Response); + Status OnRead(RpcMessage* p_Request, RpcMessage* p_Response); + Status OnList(RpcMessage* p_Request, RpcMessage* p_Response); + Status OnStat(RpcMessage* p_Request, RpcMessage* p_Response); + Status OnMkdir(RpcMessage* p_Request, RpcMessage* p_Response); + Status OnUnlink(RpcMessage* p_Request, RpcMessage* p_Response); + }; + } +} \ No newline at end of file diff --git a/daemon/src/Rpc/Listener.hpp b/daemon/src/Rpc/Listener.hpp index 4dee45c3..fc17b03d 100644 --- a/daemon/src/Rpc/Listener.hpp +++ b/daemon/src/Rpc/Listener.hpp @@ -1,41 +1,55 @@ #pragma once -#include +#include "Status.hpp" -#include -#include +#ifdef _PROTOBUF +#include "Protos/Rpc.pb.h" +#endif + +#include namespace Mira { namespace Rpc { - class Connection; + class RpcMessage; + enum class Status; class Listener { - private: - RpcCategory m_Category; - uint32_t m_Type; - std::function m_Callback; + protected: + #ifdef _PROTOBUF + google::protobuf::Arena* m_Arena; + #endif public: - Listener(RpcCategory p_Category, uint32_t p_Type, std::function p_Callback) : - m_Category(p_Category), - m_Type(p_Type), - m_Callback(p_Callback) + #ifdef _PROTOBUF + Listener(google::protobuf::Arena* p_Arena) : + m_Arena(p_Arena) + #endif + Listener(void* p_Pointer) { - + } - ~Listener() + virtual ~Listener() { } + virtual Status OnMessage(RpcMessage* p_Request, RpcMessage* p_Response) = 0; + + template + void SetInnerMessage(RpcMessage* p_Message, T& p_InnerMessage) { - m_Category = RpcCategory_NONE; - m_Type = 0; - m_Callback = nullptr; - } + #if _PROTOBUF + auto s_Any = google::protobuf::Arena::CreateMessage(m_Arena); + if (!s_Any) + { + WriteLog(LL_Error, "could not create new any."); + return; + } + + s_Any->PackFrom(p_InnerMessage); - RpcCategory GetCategory() const { return m_Category; } - uint32_t GetType() const { return m_Type; } - auto GetCallback() const { return m_Callback; } + p_Message->set_allocated_inner_message(s_Any); + #endif + } }; } } \ No newline at end of file diff --git a/daemon/src/Rpc/Manager.cpp b/daemon/src/Rpc/Manager.cpp index a2bb6df5..3ea9a397 100644 --- a/daemon/src/Rpc/Manager.cpp +++ b/daemon/src/Rpc/Manager.cpp @@ -1,14 +1,38 @@ #include "Manager.hpp" -#include "Listener.hpp" -#include "Rpc/Connection.hpp" -#include +#include + +#ifdef _PROTOBUF +#include "Protos/Rpc.pb.h" +#endif +#include "Connection.hpp" +#include "FileManagerListener.hpp" +#include "Status.hpp" + +#include + +extern "C" +{ + #include +} using namespace Mira::Rpc; -Manager::Manager() +Manager::Manager() : + m_Socket(-1), + m_Port(0), + m_Address { 0 }, + m_NextConnectionId(0) { + // Add default listeners + /*m_Listeners.push_back(std::make_shared( + #ifdef _PROTOBUF + &m_Arena + #endif + ));*/ + // Make this baby prrrr + Startup(); } Manager::~Manager() @@ -16,165 +40,280 @@ Manager::~Manager() } -// idk: https://stackoverflow.com/questions/20833453/comparing-stdfunctions-for-equality -template -size_t getAddress(std::function f) +// Closes the socket +void Manager::Internal_CloseSocket() { - typedef T(fnType)(U...); - fnType** fnPointer = f.template target(); - return (size_t)*fnPointer; + if (m_Socket == -1) + return; + + shutdown(m_Socket, SHUT_RDWR); + close(m_Socket); + m_Socket = -1; } -bool Manager::Register(RpcCategory p_Category, uint32_t p_Type, std::function p_Callback) +bool Manager::Startup() { - // Check if we have reached our max - if (m_Listeners.size() >= Manager_MaxListeners) + // Acquire the manager lock + std::lock_guard s_LockGuard(m_Mutex); + + WriteLog(LL_Debug, "Rpc Server Starting..."); + + // Close the socket if we already had one (stale) + if (m_Socket != -1) + Internal_CloseSocket(); + + // Create a new socket + m_Socket = socket(AF_INET, SOCK_STREAM, 0); + if (m_Socket == -1) { - fprintf(stderr, "err: reached maximum listener count (%lu)/(%d).\n", m_Listeners.size(), Manager_MaxListeners); + WriteLog(LL_Error, "could not create socket (%d).", errno); return false; } - // Check for duplicates - auto s_It = std::find_if(m_Listeners.begin(), m_Listeners.end(), [&] (std::shared_ptr& p_Listener) + // Find an open port + WriteLog(LL_Info, "Finding open port..."); + for (uint16_t l_PortNumber = static_cast(Options::DefaultPort); l_PortNumber < static_cast(Options::MaxDefaultPort); ++l_PortNumber) { - if (p_Listener == nullptr) - return false; + // Set our server to listen on 0.0.0.0: + memset(&m_Address, 0, sizeof(m_Address)); + m_Address.sin_family = AF_INET; + m_Address.sin_addr.s_addr = htonl(INADDR_ANY); + m_Address.sin_port = htons(static_cast(l_PortNumber)); + //m_Address.sin_len = sizeof(m_Address); - auto s_CallbackAddress = getAddress(p_Listener->GetCallback()); - auto s_TargetAddress = getAddress(p_Callback); - - if (s_CallbackAddress == s_TargetAddress && - p_Listener->GetCategory() == p_Category && - p_Listener->GetType() == p_Type) + WriteLog(LL_Debug, "Attempting to bind on port (%d).", l_PortNumber); + auto l_Ret = bind(m_Socket, reinterpret_cast(&m_Address), sizeof(m_Address)); + if (l_Ret == -1) { - return true; + WriteLog(LL_Error, "could not bind socket (%d) to port (%d).", m_Socket, l_PortNumber); + continue; } - return false; - }); + // Save the port number + m_Port = static_cast(l_PortNumber); + WriteLog(LL_Info, "Socket (%d) bound to port (%d).", m_Socket, m_Port); + break; + } - // If there is a duplicate reject it - if (s_It != m_Listeners.end()) + // Listen for new connections + WriteLog(LL_Info, "Attempting to listen for new connections..."); + auto s_Ret = listen(m_Socket, static_cast(Options::MaxConnections)); + if (s_Ret == -1) { - fprintf(stderr, "err: duplicate message listener is attempting to be registered cat (%d) type (%d).\n", p_Category, p_Type); + Internal_CloseSocket(); + WriteLog(LL_Error, "could not listen for any connections (%d).", errno); return false; } - // Create a new listener - auto s_Listener = std::make_shared(p_Category, p_Type, p_Callback); - if (s_Listener == nullptr) + // Set up the new client pump loop + m_ServerThread = std::thread([=]() { - fprintf(stderr, "err: could not allocate message listener for cat (%d) type (%d).\n", p_Category, p_Type); - return false; - } + struct timeval s_Timeout + { + .tv_sec = 0, + .tv_usec = 0, + }; - // Add it to our listeners - std::lock_guard s_Guard(m_Lock); - m_Listeners.push_back(std::move(s_Listener)); + int32_t s_ClientSocket = -1; + struct sockaddr_in s_ClientAddress = { 0 }; + socklen_t s_ClientAddressLength = sizeof(s_ClientAddress); - return true; -} + // Iterate accepting the socket + while ((s_ClientSocket = accept(m_Socket, reinterpret_cast(&s_ClientAddress), &s_ClientAddressLength)) > 0) + { + // Set the linger timeout to 0 to close sockets immediately + auto l_Ret = setsockopt(m_Socket, SOL_SOCKET, SO_LINGER, &s_Timeout, sizeof(s_Timeout)); + if (l_Ret == -1) + { + WriteLog(LL_Error, "could not set socket linger timeout (%d).", errno); + shutdown(s_ClientSocket, SHUT_RDWR); + close(s_ClientSocket); + continue; + } -bool Manager::Unregister(RpcCategory p_Category, uint32_t p_Type, std::function p_Callback) -{ - std::lock_guard s_Guard(m_Lock); + // Debug logging + uint32_t l_Address = static_cast(s_ClientAddress.sin_addr.s_addr); + WriteLog(LL_Debug, "got new rpc connection (%d) from IP (%03d.%03d.%03d.%03d).", + s_ClientSocket, + (l_Address & 0xFF), + (l_Address >> 8) & 0xFF, + (l_Address >> 16) & 0xFF, + (l_Address >> 24) & 0xFF); + + // Create the connection which handles the message pump + auto l_Connection = std::make_shared(s_ClientSocket, s_ClientSocket, s_ClientAddress, std::bind(&Manager::OnConnectionDisconnect, this, std::placeholders::_1)); + if (l_Connection == nullptr) + { + WriteLog(LL_Error, "could not allocate connection."); + shutdown(s_ClientSocket, SHUT_RDWR); + close(s_ClientSocket); + continue; + } - auto s_Item = std::remove_if(m_Listeners.begin(), m_Listeners.end(), [&](const std::shared_ptr p_Listener) - { - if (!p_Listener) - return false; - - return p_Listener->GetCategory() == p_Category && - p_Listener->GetType() == p_Type && - getAddress(p_Listener->GetCallback()) == getAddress(p_Callback); - }); + { + std::lock_guard s_LockGuard(m_Mutex); + m_Connections.push_back(l_Connection); + } - if (s_Item == m_Listeners.end()) - return false; - - // Remove from the list - m_Listeners.erase(s_Item); + // Create a new client thread + std::thread l_ConnectionThread([=]() + { + WriteLog(LL_Info, "rpc connection thread created socket: (%d), addr: (%p)", + l_Connection->GetSocket(), + l_Connection.get()); + + auto s_Socket = l_Connection->GetSocket(); - return true; -} + uint64_t s_IncomingMessageSize = 0; + ssize_t s_Ret = -1; -void Manager::Clear() -{ - std::lock_guard s_Guard(m_Lock); - m_Listeners.clear(); -} + while ((s_Ret = recv(s_Socket, &s_IncomingMessageSize, sizeof(s_IncomingMessageSize), 0)) > 0) + { + // Verify we got enough data for the incoming size + if (s_Ret != sizeof(s_IncomingMessageSize)) + { + WriteLog(LL_Error, "could not get incoming message size."); + break; + } -void Manager::SendErrorResponse(std::shared_ptr p_Connection, RpcCategory p_Category, int32_t p_Error) -{ - if (!p_Connection) - return; - - SendResponse(p_Connection, p_Category, static_cast(0), p_Error < 0 ? p_Error : (-p_Error), std::vector()); -} + if (s_IncomingMessageSize > static_cast(Options::MaxIncomingMessageSize)) + { + WriteLog(LL_Error, "Incoming message size (0x%lx) > max message size (0x%lx).", s_IncomingMessageSize, Options::MaxIncomingMessageSize); + break; + } -void Manager::SendResponse(std::shared_ptr p_Connection, RpcCategory p_Category, uint32_t p_Type, int64_t p_Error, std::vector p_Data) -{ - if (p_Connection == nullptr) - return; + // Internal data + std::vector s_IncomingData; + s_IncomingData.resize(s_IncomingMessageSize, 0); - auto s_Socket = p_Connection->GetSocket(); - if (s_Socket < 0) - return; - - flatbuffers::FlatBufferBuilder s_Builder; + // Get the data from the wire + s_Ret = recv(s_Socket, s_IncomingData.data(), s_IncomingMessageSize, 0); + if (s_Ret != s_IncomingMessageSize) + { + WriteLog(LL_Error, "did not get the correct amount of data (0x%lx) wanted (0x%lx).", s_Ret, s_IncomingMessageSize); + break; + } - // Create a new vector - auto s_DataVector = s_Builder.CreateVector(p_Data.data(), p_Data.size()); + #if _PROTOBUF - // Create a new header - auto s_Header = CreateRpcHeader(s_Builder, RpcMagics::RpcMagics_Version2, p_Category, p_Type, 0, p_Error, s_DataVector); + // Create the new request and responses + auto s_Request = google::protobuf::Arena::CreateMessage(&m_Arena); + if (s_Request == nullptr) + { + WriteLog(LL_Error, "could not allocate new request."); + break; + } - // Finalize the header - s_Builder.Finish(s_Header); + auto s_Response = google::protobuf::Arena::CreateMessage(&m_Arena); + if (s_Response == nullptr) + { + WriteLog(LL_Error, "could not allocate new response."); + break; + } - // Get the buffer pointer and size - auto s_BufferPointer = s_Builder.GetBufferPointer(); - auto s_BufferSize = s_Builder.GetSize(); + // Attempt to parse the incoming data + if (!s_Request->ParseFromArray(s_IncomingData.data(), s_IncomingData.size())) + { + WriteLog(LL_Error, "could not parse RpcMessage from incoming data, is it malformed?"); + continue; + } - printf("info: buf: (%p), size: (%x).\n", s_BufferPointer, s_BufferSize); + // Validate the magic + if (s_Request->magic() != RpcMessage_Magic::RpcMessage_Magic_V3) + { + WriteLog(LL_Error, "incompatible version of RpcMessage (%d).", s_Request->magic()); + continue; + } - auto s_Ret = write(s_Socket, s_BufferPointer, s_BufferSize); - if (s_Ret <= 0) - { - fprintf(stderr, "could not write to socket (%ld).\n", s_Ret); - return; - } + // Validate the category + auto s_Category = s_Request->category(); + if (s_Category <= RpcMessage_RpcCategory_NO_CATEGORY || + s_Category >= RpcMessage_RpcCategory_RPC_COUNT) + { + WriteLog(LL_Error, "invalid category (%d).", s_Category); + continue; + } + + // Iterate through all of our listeners + for (auto l_Listener : m_Listeners) + { + auto l_Status = l_Listener->OnMessage(s_Request, s_Response); + + // This could mean that the listener does not support this message + if (l_Status == Status::SKIPPED) + continue; + + // This means stop processing all together and go back to listening for messages + if (l_Status == Status::CANCELLED) + break; + + // These always get forced + s_Response->set_magic(RpcMessage_Magic_V3); + + std::string s_OutgoingData; + if (!s_Response->SerializeToString(&s_OutgoingData)) + { + WriteLog(LL_Error, "could not serialize outgoing data."); + break; + } + + // Write back the response + uint64_t s_OutgoingDataSize = s_OutgoingData.size(); + s_Ret = write(l_Connection->GetSocket(), &s_OutgoingDataSize, sizeof(s_OutgoingDataSize)); + if (s_Ret == -1) + { + WriteLog(LL_Error, "could not write the outgoing data size (%d).", errno); + break; + } + + s_Ret = write(l_Connection->GetSocket(), s_OutgoingData.data(), s_OutgoingData.size()); + if (s_Ret == -1) + { + WriteLog(LL_Error, "could not write response back to wire (%d).", errno); + break; + } + + // Once we get a success, then we stop processing + // There should only be ONE endpoint per-message type + break; + } + #endif + } + + OnConnectionDisconnect(l_Connection->GetId()); + }); + + l_ConnectionThread.detach(); + + // Zero out the address + memset(&s_ClientAddress, 0, sizeof(s_ClientAddress)); + + } + }); + + // Kick the thread off + m_ServerThread.detach(); + return true; } -void Manager::OnRequest(Rpc::Connection* p_Connection, const Mira::Rpc::RpcHeader* p_Message) +void Manager::OnConnectionDisconnect(uint64_t p_ConnectionId) { - if (p_Connection == nullptr) - return; - - if (p_Message == nullptr) - return; - - std::lock_guard s_Guard(m_Lock); - std::for_each(m_Listeners.begin(), m_Listeners.end(), [&](std::shared_ptr p_Listener) + WriteLog(LL_Info, "shutting down connection (%d).", p_ConnectionId); + + auto s_Found = std::find_if(m_Connections.begin(), m_Connections.end(), [&](std::shared_ptr p_IterConnection) { - // Validate the listener - if (p_Listener == nullptr) - return; - - // Validate the category - if (p_Listener->GetCategory() != p_Message->category()) - return; - - // Validate the type - if (p_Listener->GetType() != p_Message->type()) - return; - - // Call the callback - auto s_Callback = p_Listener->GetCallback(); - if (s_Callback == nullptr) - return; - - // Call the callback - s_Callback(p_Connection, p_Message); + return p_IterConnection->GetId() == p_ConnectionId; }); + + if (s_Found != m_Connections.end()) + { + auto s_Connection = (*s_Found).get(); + + shutdown(s_Connection->GetSocket(), SHUT_RDWR); + close(s_Connection->GetSocket()); + + m_Connections.erase(s_Found); + + WriteLog(LL_Debug, "client removed from connections list."); + } } \ No newline at end of file diff --git a/daemon/src/Rpc/Manager.hpp b/daemon/src/Rpc/Manager.hpp index 0ae8cc30..367bd843 100644 --- a/daemon/src/Rpc/Manager.hpp +++ b/daemon/src/Rpc/Manager.hpp @@ -1,47 +1,72 @@ #pragma once -#include #include #include #include +#include #include +#include + +#ifdef _PROTOBUF +#include +#endif + +extern "C" +{ + #include + #include +}; namespace Mira { namespace Rpc { - struct RpcHeader; - class Connection; class Listener; + class Connection; class Manager { private: - enum + enum class Options { - Manager_MaxCategories = std::numeric_limits::max() - 1, - Manager_MaxListeners = 64, + DefaultPort = 9999, + MaxDefaultPort = 10020, + MaxConnections = 8, - // Maximum message size (4MB) - Manager_MaxMessageSize = 0x4000000, + MaxIncomingMessageSize = 0x4000000, // 64 Megabytes + MaxOutgoingMessageSize = 0x4000000, // 64 Megabytes }; + // + // Server socket code + // + int32_t m_Socket; + int16_t m_Port; + struct sockaddr_in m_Address; - std::vector> m_Listeners; - std::mutex m_Lock; + #ifdef _PROTOBUF + google::protobuf::Arena m_Arena; + #endif + std::mutex m_Mutex; + // Internal tracker for the listeners + std::vector> m_Listeners; + + uint64_t m_NextConnectionId; + std::vector> m_Connections; + + std::thread m_ServerThread; public: Manager(); virtual ~Manager(); - bool Register(RpcCategory p_Category, uint32_t p_Type, std::function); - bool Unregister(RpcCategory p_Category, uint32_t p_Type, std::function); + protected: + bool Startup(); - void Clear(); - - void SendErrorResponse(std::shared_ptr p_Connection, RpcCategory p_Category, int32_t p_Error); - - void SendResponse(std::shared_ptr p_Connection, RpcCategory p_Category, uint32_t p_Type, int64_t p_Error, std::vector p_Data); + private: + void OnIncomingMessage(); + void OnConnectionDisconnect(uint64_t p_ConnectionId); - void OnRequest(Rpc::Connection* p_Connection, const Mira::Rpc::RpcHeader* p_Message); + // Internal functions do not lock, be warned! + void Internal_CloseSocket(); }; } } \ No newline at end of file diff --git a/daemon/src/Rpc/Protos/Debugger.proto b/daemon/src/Rpc/Protos/Debugger.proto new file mode 100644 index 00000000..9260279a --- /dev/null +++ b/daemon/src/Rpc/Protos/Debugger.proto @@ -0,0 +1,149 @@ +syntax = "proto3"; + +service DebuggerService { + // + // Debugger + // + rpc Attach (AttachRequest) returns (AttachResponse); + rpc Detach (DetachRequest) returns (DetachResponse); + rpc Reparent (ReparentRequest) returns (ReparentResponse); + + // + // Breakpoints + // + rpc SetBreakpoint (SetBreakpointRequest) returns (SetBreakpointResponse); + rpc DeleteBreakpoint (DeleteBreakpointRequest) returns (DeleteBreakpointResponse); + rpc GetBreakpoint (GetBreakpointRequest) returns (GetBreakpointResponse); + rpc GetAllBreakpoints (GetAllBreakpointsRequest) returns (stream Breakpoint); + + // + // Flow control + // + rpc Run (RunRequest) returns (RunResponse); + rpc Break (BreakRequest) returns (BreakResponse); + rpc Step (StepRequest) returns (StepResponse); + + + // + // Process & Thread info + // + + rpc GetProcessList (GetProcessListRequest) returns (stream GetP); + +} + +// +// Debugger +// + +message AttachRequest { + // Process id to attach + int32 process_id = 1; + + // Should we pause the process on attach + bool break_on_attach = 2; +} + +message AttachResponse { + int32 error = 1; +} + +message DetachRequest { + int32 process_id = 1; + + bool run_on_detach = 2; + + bool should_reparent = 3; + + int32 reparent_id = 4; +} + +message DetachResponse { + int32 error = 1; +} + +message ReparentRequest { + int32 process_id = 1; + + int32 reparent_id = 2; +} + +message ReparentResponse { + int32 error = 1; +} + +// +// Breakpoints +// +message Breakpoint { + // Breakpoint id + uint64 id = 1; + + // Is this a hardware breakpoint (you only have 4) + bool is_hardware = 2; + + // Is this breakpoint enabled + bool is_enabled = 3; + + // Address of the breakpoint + uint64 address = 4; + + // Breakpoint size, (1, 2, 4, 8?, are only valid) + uint32 length = 5; + + // Current hit count + uint64 hit_count = 6; + + // Bytes backed up + bytes backup = 7; +} + +message SetBreakpointRequest { + bool is_hardware = 1; + + bool is_enabled = 2; + + uint64 address = 3; + + uint32 length = 4; +} + +message SetBreakpointResponse { + int32 error = 1; + + uint64 id = 2; +} + +message GetBreakpointRequest { + uint64 id = 1; +} + +message GetBreakpointResponse { + int32 error = 1; + + Breakpoint breakpoint = 2; +} + +message GetAllBreakpointsRequest { + +} + +// +// Flow control +// +message RunRequest { +} + +message RunResponse { + int32 error = 1; +} + +message BreakRequest { +} + +message BreakResponse { + int32 error = 1; +} + +message StepRequest { +} \ No newline at end of file diff --git a/daemon/src/Rpc/Protos/FileManager.pb.cpp b/daemon/src/Rpc/Protos/FileManager.pb.cpp new file mode 100644 index 00000000..08a98536 --- /dev/null +++ b/daemon/src/Rpc/Protos/FileManager.pb.cpp @@ -0,0 +1,6097 @@ +#ifdef _PROTOBUF +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: FileManager.proto + +#include "FileManager.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) +#include +extern PROTOBUF_INTERNAL_EXPORT_FileManager_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_ListEntry_FileManager_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_FileManager_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Time_FileManager_2eproto; +namespace Mira { +namespace Rpc { +namespace FileManager { +class EmptyReplyDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _EmptyReply_default_instance_; +class EchoRequestDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _EchoRequest_default_instance_; +class OpenRequestDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _OpenRequest_default_instance_; +class OpenResponseDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _OpenResponse_default_instance_; +class CloseRequestDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _CloseRequest_default_instance_; +class CloseResponseDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _CloseResponse_default_instance_; +class SeekRequestDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _SeekRequest_default_instance_; +class SeekResponseDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _SeekResponse_default_instance_; +class ReadRequestDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _ReadRequest_default_instance_; +class ReadResponseDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _ReadResponse_default_instance_; +class WriteRequestDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _WriteRequest_default_instance_; +class WriteResponseDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _WriteResponse_default_instance_; +class ListRequestDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _ListRequest_default_instance_; +class ListEntryDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _ListEntry_default_instance_; +class ListResponseDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _ListResponse_default_instance_; +class StatRequestDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; +} _StatRequest_default_instance_; +class TimeDefaultTypeInternal { + public: + ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed